chore(libs): sync Ace3 to coa-ace3 (WoWUIDev master @ 52e5f2c)

Bring every embedded Ace3 / CallbackHandler / LibStub copy in line with the
canonical Exiles/coa-ace3 bundle so LibStub resolution is predictable across
all Exiles forks regardless of which addons are enabled.

Libraries updated in this fork:
  AceAddon-3.0           13  (5 → 13)
  AceConfig-3.0          3  (2 → 3)
  AceConfigCmd-3.0       14  (12 → 14)
  AceConfigDialog-3.0    92  (43 → 92)
  AceConfigRegistry-3.0  22  (11 → 22)
  AceConsole-3.0         7
  AceDB-3.0              33  (19 → 33)
  AceDBOptions-3.0       15  (11 → 15)
  AceEvent-3.0           4  (3 → 4)
  AceGUI-3.0             41  (30 → 41)
  AceLocale-3.0          6  (2 → 6)
  AceTimer-3.0           17  (5 → 17)
  CallbackHandler-1.0    8  (3 → 8)
  LibStub                2
This commit is contained in:
2026-05-23 13:42:18 +02:00
parent b6d42dfe5d
commit b2cf327cd9
58 changed files with 13358 additions and 13030 deletions
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -1,4 +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/ <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"> ..\FrameXML\UI.xsd">
<Script file="AceAddon-3.0.lua"/> <Script file="AceAddon-3.0.lua"/>
</Ui> </Ui>
+58 -57
View File
@@ -1,57 +1,58 @@
--- AceConfig-3.0 wrapper library. --- AceConfig-3.0 wrapper library.
-- Provides an API to register an options table with the config registry, -- Provides an API to register an options table with the config registry,
-- as well as associate it with a slash command. -- as well as associate it with a slash command.
-- @class file -- @class file
-- @name AceConfig-3.0 -- @name AceConfig-3.0
-- @release $Id: AceConfig-3.0.lua 877 2009-11-02 15:56:50Z nevcairiel $ -- @release $Id$
--[[ --[[
AceConfig-3.0 AceConfig-3.0
Very light wrapper library that combines all the AceConfig subcomponents into one more easily used whole. Very light wrapper library that combines all the AceConfig subcomponents into one more easily used whole.
]] ]]
local MAJOR, MINOR = "AceConfig-3.0", 2 local cfgreg = LibStub("AceConfigRegistry-3.0")
local AceConfig = LibStub:NewLibrary(MAJOR, MINOR) local cfgcmd = LibStub("AceConfigCmd-3.0")
if not AceConfig then return end local MAJOR, MINOR = "AceConfig-3.0", 3
local AceConfig = LibStub:NewLibrary(MAJOR, MINOR)
local cfgreg = LibStub("AceConfigRegistry-3.0")
local cfgcmd = LibStub("AceConfigCmd-3.0") if not AceConfig then return end
local cfgdlg = LibStub("AceConfigDialog-3.0")
--TODO: local cfgdrp = LibStub("AceConfigDropdown-3.0") --TODO: local cfgdlg = LibStub("AceConfigDialog-3.0", true)
--TODO: local cfgdrp = LibStub("AceConfigDropdown-3.0", true)
-- Lua APIs
local pcall, error, type, pairs = pcall, error, type, pairs -- Lua APIs
local pcall, error, type, pairs = pcall, error, type, pairs
-- -------------------------------------------------------------------
-- :RegisterOptionsTable(appName, options, slashcmd, persist) -- -------------------------------------------------------------------
-- -- :RegisterOptionsTable(appName, options, slashcmd)
-- - appName - (string) application name --
-- - options - table or function ref, see AceConfigRegistry -- - appName - (string) application name
-- - slashcmd - slash command (string) or table with commands, or nil to NOT create a slash command -- - options - table or function ref, see AceConfigRegistry
-- - slashcmd - slash command (string) or table with commands, or nil to NOT create a slash command
--- Register a option table with the AceConfig registry.
-- You can supply a slash command (or a table of slash commands) to register with AceConfigCmd directly. --- Register a option table with the AceConfig registry.
-- @paramsig appName, options [, slashcmd] -- You can supply a slash command (or a table of slash commands) to register with AceConfigCmd directly.
-- @param appName The application name for the config table. -- @paramsig appName, options [, slashcmd]
-- @param options The option table (or a function to generate one on demand) -- @param appName The application name for the config table.
-- @param slashcmd A slash command to register for the option table, or a table of slash commands. -- @param options The option table (or a function to generate one on demand). http://www.wowace.com/addons/ace3/pages/ace-config-3-0-options-tables/
-- @usage -- @param slashcmd A slash command to register for the option table, or a table of slash commands.
-- local AceConfig = LibStub("AceConfig-3.0") -- @usage
-- AceConfig:RegisterOptionsTable("MyAddon", myOptions, {"/myslash", "/my"}) -- local AceConfig = LibStub("AceConfig-3.0")
function AceConfig:RegisterOptionsTable(appName, options, slashcmd) -- AceConfig:RegisterOptionsTable("MyAddon", myOptions, {"/myslash", "/my"})
local ok,msg = pcall(cfgreg.RegisterOptionsTable, self, appName, options) function AceConfig:RegisterOptionsTable(appName, options, slashcmd)
if not ok then error(msg, 2) end 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 if slashcmd then
for _,cmd in pairs(slashcmd) do if type(slashcmd) == "table" then
cfgcmd:CreateChatCommand(cmd, appName) for _,cmd in pairs(slashcmd) do
end cfgcmd:CreateChatCommand(cmd, appName)
else end
cfgcmd:CreateChatCommand(slashcmd, appName) else
end cfgcmd:CreateChatCommand(slashcmd, appName)
end end
end end
end
+7 -7
View File
@@ -1,8 +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/ <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"> ..\FrameXML\UI.xsd">
<Include file="AceConfigRegistry-3.0\AceConfigRegistry-3.0.xml"/> <Include file="AceConfigRegistry-3.0\AceConfigRegistry-3.0.xml"/>
<Include file="AceConfigCmd-3.0\AceConfigCmd-3.0.xml"/> <Include file="AceConfigCmd-3.0\AceConfigCmd-3.0.xml"/>
<Include file="AceConfigDialog-3.0\AceConfigDialog-3.0.xml"/> <Include file="AceConfigDialog-3.0\AceConfigDialog-3.0.xml"/>
<!--<Include file="AceConfigDropdown-3.0\AceConfigDropdown-3.0.xml"/>--> <!--<Include file="AceConfigDropdown-3.0\AceConfigDropdown-3.0.xml"/>-->
<Script file="AceConfig-3.0.lua"/> <Script file="AceConfig-3.0.lua"/>
</Ui> </Ui>
File diff suppressed because it is too large Load Diff
@@ -1,4 +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/ <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"> ..\FrameXML\UI.xsd">
<Script file="AceConfigCmd-3.0.lua"/> <Script file="AceConfigCmd-3.0.lua"/>
</Ui> </Ui>
File diff suppressed because it is too large Load Diff
@@ -1,4 +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/ <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"> ..\FrameXML\UI.xsd">
<Script file="AceConfigDialog-3.0.lua"/> <Script file="AceConfigDialog-3.0.lua"/>
</Ui> </Ui>
@@ -1,344 +1,373 @@
--- AceConfigRegistry-3.0 handles central registration of options tables in use by addons and modules.\\ --- AceConfigRegistry-3.0 handles central registration of options tables in use by addons and modules.\\
-- Options tables can be registered as raw tables, OR as function refs that return a table.\\ -- Options tables can be registered as raw tables, OR as function refs that return a table.\\
-- Such functions receive three arguments: "uiType", "uiName", "appName". \\ -- Such functions receive three arguments: "uiType", "uiName", "appName". \\
-- * Valid **uiTypes**: "cmd", "dropdown", "dialog". This is verified by the library at call time. \\ -- * 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.\\ -- * 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.\\
-- * The **appName** field is the options table name as given at registration time \\ -- * The **appName** field is the options table name as given at registration time \\
-- --
-- :IterateOptionsTables() (and :GetOptionsTable() if only given one argument) return a function reference that the requesting config handling addon must call with valid "uiType", "uiName". -- :IterateOptionsTables() (and :GetOptionsTable() if only given one argument) return a function reference that the requesting config handling addon must call with valid "uiType", "uiName".
-- @class file -- @class file
-- @name AceConfigRegistry-3.0 -- @name AceConfigRegistry-3.0
-- @release $Id: AceConfigRegistry-3.0.lua 890 2009-12-06 12:50:05Z nevcairiel $ -- @release $Id$
local MAJOR, MINOR = "AceConfigRegistry-3.0", 11 local CallbackHandler = LibStub("CallbackHandler-1.0")
local AceConfigRegistry = LibStub:NewLibrary(MAJOR, MINOR)
local MAJOR, MINOR = "AceConfigRegistry-3.0", 22
if not AceConfigRegistry then return end local AceConfigRegistry = LibStub:NewLibrary(MAJOR, MINOR)
AceConfigRegistry.tables = AceConfigRegistry.tables or {} if not AceConfigRegistry then return end
local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0") AceConfigRegistry.tables = AceConfigRegistry.tables or {}
if not AceConfigRegistry.callbacks then if not AceConfigRegistry.callbacks then
AceConfigRegistry.callbacks = CallbackHandler:New(AceConfigRegistry) AceConfigRegistry.callbacks = CallbackHandler:New(AceConfigRegistry)
end end
-- Lua APIs -- Lua APIs
local tinsert, tconcat = table.insert, table.concat local tinsert, tconcat = table.insert, table.concat
local strfind, strmatch = string.find, string.match local strfind, strmatch = string.find, string.match
local type, tostring, select, pairs = type, tostring, select, pairs local type, tostring, select, pairs = type, tostring, select, pairs
local error, assert = error, assert local error, assert = error, assert
----------------------------------------------------------------------- -----------------------------------------------------------------------
-- Validating options table consistency: -- Validating options table consistency:
AceConfigRegistry.validated = { AceConfigRegistry.validated = {
-- list of options table names ran through :ValidateOptionsTable automatically. -- list of options table names ran through :ValidateOptionsTable automatically.
-- CLEARED ON PURPOSE, since newer versions may have newer validators -- CLEARED ON PURPOSE, since newer versions may have newer validators
cmd = {}, cmd = {},
dropdown = {}, dropdown = {},
dialog = {}, dialog = {},
} }
local function err(msg, errlvl, ...) local function err(msg, errlvl, ...)
local t = {} local t = {}
for i=select("#",...),1,-1 do for i=select("#",...),1,-1 do
tinsert(t, (select(i, ...))) tinsert(t, (select(i, ...)))
end end
error(MAJOR..":ValidateOptionsTable(): "..tconcat(t,".")..msg, errlvl+2) error(MAJOR..":ValidateOptionsTable(): "..tconcat(t,".")..msg, errlvl+2)
end end
local isstring={["string"]=true, _="string"} local isstring={["string"]=true, _="string"}
local isstringfunc={["string"]=true,["function"]=true, _="string or funcref"} local isstringfunc={["string"]=true,["function"]=true, _="string or funcref"}
local istable={["table"]=true, _="table"} local istable={["table"]=true, _="table"}
local ismethodtable={["table"]=true,["string"]=true,["function"]=true, _="methodname, funcref or table"} local ismethodtable={["table"]=true,["string"]=true,["function"]=true, _="methodname, funcref or table"}
local optstring={["nil"]=true,["string"]=true, _="string"} local optstring={["nil"]=true,["string"]=true, _="string"}
local optstringfunc={["nil"]=true,["string"]=true,["function"]=true, _="string or funcref"} local optstringfunc={["nil"]=true,["string"]=true,["function"]=true, _="string or funcref"}
local optnumber={["nil"]=true,["number"]=true, _="number"} local optstringnumberfunc={["nil"]=true,["string"]=true,["number"]=true,["function"]=true, _="string, number or funcref"}
local optmethod={["nil"]=true,["string"]=true,["function"]=true, _="methodname or funcref"} local optnumber={["nil"]=true,["number"]=true, _="number"}
local optmethodfalse={["nil"]=true,["string"]=true,["function"]=true,["boolean"]={[false]=true}, _="methodname, funcref or false"} 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 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 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 optmethodbool={["nil"]=true,["string"]=true,["function"]=true,["boolean"]=true, _="methodname, funcref or boolean"}
local opttable={["nil"]=true,["table"]=true, _="table"} local opttable={["nil"]=true,["table"]=true, _="table"}
local optbool={["nil"]=true,["boolean"]=true, _="boolean"} local optbool={["nil"]=true,["boolean"]=true, _="boolean"}
local optboolnumber={["nil"]=true,["boolean"]=true,["number"]=true, _="boolean or number"} local optboolnumber={["nil"]=true,["boolean"]=true,["number"]=true, _="boolean or number"}
local optstringnumber={["nil"]=true,["string"]=true,["number"]=true, _="string or number"}
local basekeys={
type=isstring, local basekeys={
name=isstringfunc, type=isstring,
desc=optstringfunc, name=isstringfunc,
descStyle=optstring, desc=optstringfunc,
order=optmethodnumber, descStyle=optstring,
validate=optmethodfalse, order=optmethodnumber,
confirm=optmethodbool, validate=optmethodfalse,
confirmText=optstring, confirm=optmethodbool,
disabled=optmethodbool, confirmText=optstring,
hidden=optmethodbool, disabled=optmethodbool,
guiHidden=optmethodbool, hidden=optmethodbool,
dialogHidden=optmethodbool, guiHidden=optmethodbool,
dropdownHidden=optmethodbool, dialogHidden=optmethodbool,
cmdHidden=optmethodbool, dropdownHidden=optmethodbool,
icon=optstringfunc, cmdHidden=optmethodbool,
iconCoords=optmethodtable, tooltipHyperlink=optstringfunc,
handler=opttable, icon=optstringnumberfunc,
get=optmethodfalse, iconCoords=optmethodtable,
set=optmethodfalse, handler=opttable,
func=optmethodfalse, get=optmethodfalse,
arg={["*"]=true}, set=optmethodfalse,
width=optstring, func=optmethodfalse,
} arg={["*"]=true},
width=optstringnumber,
local typedkeys={ relWidth=optnumber,
header={}, }
description={
image=optstringfunc, local typedkeys={
imageCoords=optmethodtable, header={
imageHeight=optnumber, control=optstring,
imageWidth=optnumber, dialogControl=optstring,
fontSize=optstringfunc, dropdownControl=optstring,
}, },
group={ description={
args=istable, image=optstringnumberfunc,
plugins=opttable, imageCoords=optmethodtable,
inline=optbool, imageHeight=optnumber,
cmdInline=optbool, imageWidth=optnumber,
guiInline=optbool, fontSize=optstringfunc,
dropdownInline=optbool, control=optstring,
dialogInline=optbool, dialogControl=optstring,
childGroups=optstring, dropdownControl=optstring,
}, },
execute={ group={
image=optstringfunc, args=istable,
imageCoords=optmethodtable, plugins=opttable,
imageHeight=optnumber, inline=optbool,
imageWidth=optnumber, cmdInline=optbool,
}, guiInline=optbool,
input={ dropdownInline=optbool,
pattern=optstring, dialogInline=optbool,
usage=optstring, childGroups=optstring,
control=optstring, },
dialogControl=optstring, execute={
dropdownControl=optstring, image=optstringnumberfunc,
multiline=optboolnumber, imageCoords=optmethodtable,
}, imageHeight=optnumber,
toggle={ imageWidth=optnumber,
tristate=optbool, control=optstring,
image=optstringfunc, dialogControl=optstring,
imageCoords=optmethodtable, dropdownControl=optstring,
}, },
tristate={ input={
}, pattern=optstring,
range={ usage=optstring,
min=optnumber, control=optstring,
max=optnumber, dialogControl=optstring,
step=optnumber, dropdownControl=optstring,
bigStep=optnumber, multiline=optboolnumber,
isPercent=optbool, },
}, toggle={
select={ tristate=optbool,
values=ismethodtable, image=optstringnumberfunc,
style={ imageCoords=optmethodtable,
["nil"]=true, control=optstring,
["string"]={dropdown=true,radio=true}, dialogControl=optstring,
_="string: 'dropdown' or 'radio'" dropdownControl=optstring,
}, },
control=optstring, tristate={
dialogControl=optstring, },
dropdownControl=optstring, range={
}, min=optnumber,
multiselect={ softMin=optnumber,
values=ismethodtable, max=optnumber,
style=optstring, softMax=optnumber,
tristate=optbool, step=optnumber,
control=optstring, bigStep=optnumber,
dialogControl=optstring, isPercent=optbool,
dropdownControl=optstring, control=optstring,
}, dialogControl=optstring,
color={ dropdownControl=optstring,
hasAlpha=optbool, },
}, select={
keybinding={ values=ismethodtable,
-- TODO sorting=optmethodtable,
}, style={
} ["nil"]=true,
["string"]={dropdown=true,radio=true},
local function validateKey(k,errlvl,...) _="string: 'dropdown' or 'radio'"
errlvl=(errlvl or 0)+1 },
if type(k)~="string" then control=optstring,
err("["..tostring(k).."] - key is not a string", errlvl,...) dialogControl=optstring,
end dropdownControl=optstring,
if strfind(k, "[%c\127]") then itemControl=optstring,
err("["..tostring(k).."] - key name contained control characters", errlvl,...) },
end multiselect={
end values=ismethodtable,
style=optstring,
local function validateVal(v, oktypes, errlvl,...) tristate=optbool,
errlvl=(errlvl or 0)+1 control=optstring,
local isok=oktypes[type(v)] or oktypes["*"] dialogControl=optstring,
dropdownControl=optstring,
if not isok then },
err(": expected a "..oktypes._..", got '"..tostring(v).."'", errlvl,...) color={
end hasAlpha=optmethodbool,
if type(isok)=="table" then -- isok was a table containing specific values to be tested for! control=optstring,
if not isok[v] then dialogControl=optstring,
err(": did not expect "..type(v).." value '"..tostring(v).."'", errlvl,...) dropdownControl=optstring,
end },
end keybinding={
end control=optstring,
dialogControl=optstring,
local function validate(options,errlvl,...) dropdownControl=optstring,
errlvl=(errlvl or 0)+1 },
-- basic consistency }
if type(options)~="table" then
err(": expected a table, got a "..type(options), errlvl,...) local function validateKey(k,errlvl,...)
end errlvl=(errlvl or 0)+1
if type(options.type)~="string" then if type(k)~="string" then
err(".type: expected a string, got a "..type(options.type), errlvl,...) err("["..tostring(k).."] - key is not a string", errlvl,...)
end end
if strfind(k, "[%c\127]") then
-- get type and 'typedkeys' member err("["..tostring(k).."] - key name contained control characters", errlvl,...)
local tk = typedkeys[options.type] end
if not tk then end
err(".type: unknown type '"..options.type.."'", errlvl,...)
end local function validateVal(v, oktypes, errlvl,...)
errlvl=(errlvl or 0)+1
-- make sure that all options[] are known parameters local isok=oktypes[type(v)] or oktypes["*"]
for k,v in pairs(options) do
if not (tk[k] or basekeys[k]) then if not isok then
err(": unknown parameter", errlvl,tostring(k),...) err(": expected a "..oktypes._..", got '"..tostring(v).."'", errlvl,...)
end end
end if type(isok)=="table" then -- isok was a table containing specific values to be tested for!
if not isok[v] then
-- verify that required params are there, and that everything is the right type err(": did not expect "..type(v).." value '"..tostring(v).."'", errlvl,...)
for k,oktypes in pairs(basekeys) do end
validateVal(options[k], oktypes, errlvl,k,...) end
end end
for k,oktypes in pairs(tk) do
validateVal(options[k], oktypes, errlvl,k,...) local function validate(options,errlvl,...)
end errlvl=(errlvl or 0)+1
-- basic consistency
-- extra logic for groups if type(options)~="table" then
if options.type=="group" then err(": expected a table, got a "..type(options), errlvl,...)
for k,v in pairs(options.args) do end
validateKey(k,errlvl,"args",...) if type(options.type)~="string" then
validate(v, errlvl,k,"args",...) err(".type: expected a string, got a "..type(options.type), errlvl,...)
end end
if options.plugins then
for plugname,plugin in pairs(options.plugins) do -- get type and 'typedkeys' member
if type(plugin)~="table" then local tk = typedkeys[options.type]
err(": expected a table, got '"..tostring(plugin).."'", errlvl,tostring(plugname),"plugins",...) if not tk then
end err(".type: unknown type '"..options.type.."'", errlvl,...)
for k,v in pairs(plugin) do end
validateKey(k,errlvl,tostring(plugname),"plugins",...)
validate(v, errlvl,k,tostring(plugname),"plugins",...) -- make sure that all options[] are known parameters
end for k,v in pairs(options) do
end if not (tk[k] or basekeys[k]) then
end err(": unknown parameter", errlvl,tostring(k),...)
end end
end end
-- verify that required params are there, and that everything is the right type
--- Validates basic structure and integrity of an options table \\ for k,oktypes in pairs(basekeys) do
-- Does NOT verify that get/set etc actually exist, since they can be defined at any depth validateVal(options[k], oktypes, errlvl,k,...)
-- @param options The table to be validated end
-- @param name The name of the table to be validated (shown in any error message) for k,oktypes in pairs(tk) do
-- @param errlvl (optional number) error level offset, default 0 (=errors point to the function calling :ValidateOptionsTable) validateVal(options[k], oktypes, errlvl,k,...)
function AceConfigRegistry:ValidateOptionsTable(options,name,errlvl) end
errlvl=(errlvl or 0)+1
name = name or "Optionstable" -- extra logic for groups
if not options.name then if options.type=="group" then
options.name=name -- bit of a hack, the root level doesn't really need a .name :-/ for k,v in pairs(options.args) do
end validateKey(k,errlvl,"args",...)
validate(options,errlvl,name) validate(v, errlvl,k,"args",...)
end end
if options.plugins then
--- Fires a "ConfigTableChange" callback for those listening in on it, allowing config GUIs to refresh. for plugname,plugin in pairs(options.plugins) do
-- You should call this function if your options table changed from any outside event, like a game event if type(plugin)~="table" then
-- or a timer. err(": expected a table, got '"..tostring(plugin).."'", errlvl,tostring(plugname),"plugins",...)
-- @param appName The application name as given to `:RegisterOptionsTable()` end
function AceConfigRegistry:NotifyChange(appName) for k,v in pairs(plugin) do
if not AceConfigRegistry.tables[appName] then return end validateKey(k,errlvl,tostring(plugname),"plugins",...)
AceConfigRegistry.callbacks:Fire("ConfigTableChange", appName) validate(v, errlvl,k,tostring(plugname),"plugins",...)
end end
end
-- ------------------------------------------------------------------- end
-- Registering and retreiving options tables: end
end
-- validateGetterArgs: helper function for :GetOptionsTable (or, rather, the getter functions returned by it)
--- Validates basic structure and integrity of an options table \\
local function validateGetterArgs(uiType, uiName, errlvl) -- Does NOT verify that get/set etc actually exist, since they can be defined at any depth
errlvl=(errlvl or 0)+2 -- @param options The table to be validated
if uiType~="cmd" and uiType~="dropdown" and uiType~="dialog" then -- @param name The name of the table to be validated (shown in any error message)
error(MAJOR..": Requesting options table: 'uiType' - invalid configuration UI type, expected 'cmd', 'dropdown' or 'dialog'", errlvl) -- @param errlvl (optional number) error level offset, default 0 (=errors point to the function calling :ValidateOptionsTable)
end function AceConfigRegistry:ValidateOptionsTable(options,name,errlvl)
if not strmatch(uiName, "[A-Za-z]%-[0-9]") then -- Expecting e.g. "MyLib-1.2" errlvl=(errlvl or 0)+1
error(MAJOR..": Requesting options table: 'uiName' - badly formatted or missing version number. Expected e.g. 'MyLib-1.2'", errlvl) name = name or "Optionstable"
end if not options.name then
end options.name=name -- bit of a hack, the root level doesn't really need a .name :-/
end
--- Register an options table with the config registry. validate(options,errlvl,name)
-- @param appName The application name as given to `:RegisterOptionsTable()` end
-- @param options The options table, OR a function reference that generates it on demand. \\
-- See the top of the page for info on arguments passed to such functions. --- Fires a "ConfigTableChange" callback for those listening in on it, allowing config GUIs to refresh.
function AceConfigRegistry:RegisterOptionsTable(appName, options) -- You should call this function if your options table changed from any outside event, like a game event
if type(options)=="table" then -- or a timer.
if options.type~="group" then -- quick sanity checker -- @param appName The application name as given to `:RegisterOptionsTable()`
error(MAJOR..": RegisterOptionsTable(appName, options): 'options' - missing type='group' member in root group", 2) function AceConfigRegistry:NotifyChange(appName)
end if not AceConfigRegistry.tables[appName] then return end
AceConfigRegistry.tables[appName] = function(uiType, uiName, errlvl) AceConfigRegistry.callbacks:Fire("ConfigTableChange", appName)
errlvl=(errlvl or 0)+1 end
validateGetterArgs(uiType, uiName, errlvl)
if not AceConfigRegistry.validated[uiType][appName] then -- -------------------------------------------------------------------
AceConfigRegistry:ValidateOptionsTable(options, appName, errlvl) -- upgradable -- Registering and retreiving options tables:
AceConfigRegistry.validated[uiType][appName] = true
end
return options -- validateGetterArgs: helper function for :GetOptionsTable (or, rather, the getter functions returned by it)
end
elseif type(options)=="function" then local function validateGetterArgs(uiType, uiName, errlvl)
AceConfigRegistry.tables[appName] = function(uiType, uiName, errlvl) errlvl=(errlvl or 0)+2
errlvl=(errlvl or 0)+1 if uiType~="cmd" and uiType~="dropdown" and uiType~="dialog" then
validateGetterArgs(uiType, uiName, errlvl) error(MAJOR..": Requesting options table: 'uiType' - invalid configuration UI type, expected 'cmd', 'dropdown' or 'dialog'", errlvl)
local tab = assert(options(uiType, uiName, appName)) end
if not AceConfigRegistry.validated[uiType][appName] then if not strmatch(uiName, "[A-Za-z]%-[0-9]") then -- Expecting e.g. "MyLib-1.2"
AceConfigRegistry:ValidateOptionsTable(tab, appName, errlvl) -- upgradable error(MAJOR..": Requesting options table: 'uiName' - badly formatted or missing version number. Expected e.g. 'MyLib-1.2'", errlvl)
AceConfigRegistry.validated[uiType][appName] = true end
end end
return tab
end --- Register an options table with the config registry.
else -- @param appName The application name as given to `:RegisterOptionsTable()`
error(MAJOR..": RegisterOptionsTable(appName, options): 'options' - expected table or function reference", 2) -- @param options The options table, OR a function reference that generates it on demand. \\
end -- See the top of the page for info on arguments passed to such functions.
end -- @param skipValidation Skip options table validation (primarily useful for extremely huge options, with a noticeable slowdown)
function AceConfigRegistry:RegisterOptionsTable(appName, options, skipValidation)
--- Returns an iterator of ["appName"]=funcref pairs if type(options)=="table" then
function AceConfigRegistry:IterateOptionsTables() if options.type~="group" then -- quick sanity checker
return pairs(AceConfigRegistry.tables) error(MAJOR..": RegisterOptionsTable(appName, options): 'options' - missing type='group' member in root group", 2)
end end
AceConfigRegistry.tables[appName] = function(uiType, uiName, errlvl)
errlvl=(errlvl or 0)+1
validateGetterArgs(uiType, uiName, errlvl)
if not AceConfigRegistry.validated[uiType][appName] and not skipValidation then
--- Query the registry for a specific options table. AceConfigRegistry:ValidateOptionsTable(options, appName, errlvl) -- upgradable
-- If only appName is given, a function is returned which you AceConfigRegistry.validated[uiType][appName] = true
-- can call with (uiType,uiName) to get the table.\\ end
-- If uiType&uiName are given, the table is returned. return options
-- @param appName The application name as given to `:RegisterOptionsTable()` end
-- @param uiType The type of UI to get the table for, one of "cmd", "dropdown", "dialog" elseif type(options)=="function" then
-- @param uiName The name of the library/addon querying for the table, e.g. "MyLib-1.0" AceConfigRegistry.tables[appName] = function(uiType, uiName, errlvl)
function AceConfigRegistry:GetOptionsTable(appName, uiType, uiName) errlvl=(errlvl or 0)+1
local f = AceConfigRegistry.tables[appName] validateGetterArgs(uiType, uiName, errlvl)
if not f then local tab = assert(options(uiType, uiName, appName))
return nil if not AceConfigRegistry.validated[uiType][appName] and not skipValidation then
end AceConfigRegistry:ValidateOptionsTable(tab, appName, errlvl) -- upgradable
AceConfigRegistry.validated[uiType][appName] = true
if uiType then end
return f(uiType,uiName,1) -- get the table for us return tab
else end
return f -- return the function else
end error(MAJOR..": RegisterOptionsTable(appName, options): 'options' - expected table or function reference", 2)
end end
end
--- Returns an iterator of ["appName"]=funcref pairs
function AceConfigRegistry:IterateOptionsTables()
return pairs(AceConfigRegistry.tables)
end
--- Query the registry for a specific options table.
-- 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.
-- @param appName The application name as given to `:RegisterOptionsTable()`
-- @param uiType The type of UI to get the table for, one of "cmd", "dropdown", "dialog"
-- @param uiName The name of the library/addon querying for the table, e.g. "MyLib-1.0"
function AceConfigRegistry:GetOptionsTable(appName, uiType, uiName)
local f = AceConfigRegistry.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
@@ -1,4 +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/ <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"> ..\FrameXML\UI.xsd">
<Script file="AceConfigRegistry-3.0.lua"/> <Script file="AceConfigRegistry-3.0.lua"/>
</Ui> </Ui>
+246 -250
View File
@@ -1,250 +1,246 @@
--- **AceConsole-3.0** provides registration facilities for slash commands. --- **AceConsole-3.0** provides registration facilities for slash commands.
-- You can register slash commands to your custom functions and use the `GetArgs` function to parse them -- You can register slash commands to your custom functions and use the `GetArgs` function to parse them
-- to your addons individual needs. -- to your addons individual needs.
-- --
-- **AceConsole-3.0** can be embeded into your addon, either explicitly by calling AceConsole:Embed(MyAddon) or by -- **AceConsole-3.0** can be embeded into your addon, either explicitly by calling AceConsole:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object -- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceConsole itself.\\ -- and can be accessed directly, without having to explicitly call AceConsole itself.\\
-- It is recommended to embed AceConsole, otherwise you'll have to specify a custom `self` on all calls you -- It is recommended to embed AceConsole, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceConsole. -- make into AceConsole.
-- @class file -- @class file
-- @name AceConsole-3.0 -- @name AceConsole-3.0
-- @release $Id: AceConsole-3.0.lua 878 2009-11-02 18:51:58Z nevcairiel $ -- @release $Id$
local MAJOR,MINOR = "AceConsole-3.0", 7 local MAJOR,MINOR = "AceConsole-3.0", 7
local AceConsole, oldminor = LibStub:NewLibrary(MAJOR, MINOR) local AceConsole, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not AceConsole then return end -- No upgrade needed if not AceConsole then return end -- No upgrade needed
AceConsole.embeds = AceConsole.embeds or {} -- table containing objects AceConsole is embedded in. AceConsole.embeds = AceConsole.embeds or {} -- table containing objects AceConsole is embedded in.
AceConsole.commands = AceConsole.commands or {} -- table containing commands registered 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 AceConsole.weakcommands = AceConsole.weakcommands or {} -- table containing self, command => func references for weak commands that don't persist through enable/disable
-- Lua APIs -- Lua APIs
local tconcat, tostring, select = table.concat, tostring, select local tconcat, tostring, select = table.concat, tostring, select
local type, pairs, error = type, pairs, error local type, pairs, error = type, pairs, error
local format, strfind, strsub = string.format, string.find, string.sub local format, strfind, strsub = string.format, string.find, string.sub
local max = math.max local max = math.max
-- WoW APIs -- WoW APIs
local _G = _G local _G = _G
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded local tmp={}
-- List them here for Mikk's FindGlobals script local function Print(self,frame,...)
-- GLOBALS: DEFAULT_CHAT_FRAME, SlashCmdList, hash_SlashCmdList local n=0
if self ~= AceConsole then
local tmp={} n=n+1
local function Print(self,frame,...) tmp[n] = "|cff33ff99"..tostring( self ).."|r:"
local n=0 end
if self ~= AceConsole then for i=1, select("#", ...) do
n=n+1 n=n+1
tmp[n] = "|cff33ff99"..tostring( self ).."|r:" tmp[n] = tostring(select(i, ...))
end end
for i=1, select("#", ...) do frame:AddMessage( tconcat(tmp," ",1,n) )
n=n+1 end
tmp[n] = tostring(select(i, ...))
end --- Print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
frame:AddMessage( tconcat(tmp," ",1,n) ) -- @paramsig [chatframe ,] ...
end -- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function)
-- @param ... List of any values to be printed
--- Print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function) function AceConsole:Print(...)
-- @paramsig [chatframe ,] ... local frame = ...
-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function) if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member?
-- @param ... List of any values to be printed return Print(self, frame, select(2,...))
function AceConsole:Print(...) else
local frame = ... return Print(self, DEFAULT_CHAT_FRAME, ...)
if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member? end
return Print(self, frame, select(2,...)) end
else
return Print(self, DEFAULT_CHAT_FRAME, ...)
end --- Formatted (using format()) print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
end -- @paramsig [chatframe ,] "format"[, ...]
-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function)
-- @param format Format string - same syntax as standard Lua format()
--- Formatted (using format()) print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function) -- @param ... Arguments to the format string
-- @paramsig [chatframe ,] "format"[, ...] function AceConsole:Printf(...)
-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function) local frame = ...
-- @param format Format string - same syntax as standard Lua format() if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member?
-- @param ... Arguments to the format string return Print(self, frame, format(select(2,...)))
function AceConsole:Printf(...) else
local frame = ... return Print(self, DEFAULT_CHAT_FRAME, format(...))
if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member? end
return Print(self, frame, format(select(2,...))) end
else
return Print(self, DEFAULT_CHAT_FRAME, format(...))
end
end
--- Register a simple chat command
-- @param command Chat command to be registered WITHOUT leading "/"
-- @param func Function to call when the slash command is being used (funcref or methodname)
-- @param persist if false, the command will be soft disabled/enabled when aceconsole is used as a mixin (default: true)
--- Register a simple chat command function AceConsole:RegisterChatCommand( command, func, persist )
-- @param command Chat command to be registered WITHOUT leading "/" if type(command)~="string" then error([[Usage: AceConsole:RegisterChatCommand( "command", func[, persist ]): 'command' - expected a string]], 2) end
-- @param func Function to call when the slash command is being used (funcref or methodname)
-- @param persist if false, the command will be soft disabled/enabled when aceconsole is used as a mixin (default: true) 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
function AceConsole:RegisterChatCommand( command, func, persist )
if type(command)~="string" then error([[Usage: AceConsole:RegisterChatCommand( "command", func[, persist ]): 'command' - expected a string]], 2) end local name = "ACECONSOLE_"..command:upper()
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 if type( func ) == "string" then
SlashCmdList[name] = function(input, editBox)
local name = "ACECONSOLE_"..command:upper() self[func](self, input, editBox)
end
if type( func ) == "string" then else
SlashCmdList[name] = function(input, editBox) SlashCmdList[name] = func
self[func](self, input, editBox) end
end _G["SLASH_"..name.."1"] = "/"..command:lower()
else AceConsole.commands[command] = name
SlashCmdList[name] = func -- non-persisting commands are registered for enabling disabling
end if not persist then
_G["SLASH_"..name.."1"] = "/"..command:lower() if not AceConsole.weakcommands[self] then AceConsole.weakcommands[self] = {} end
AceConsole.commands[command] = name AceConsole.weakcommands[self][command] = func
-- non-persisting commands are registered for enabling disabling end
if not persist then return true
if not AceConsole.weakcommands[self] then AceConsole.weakcommands[self] = {} end end
AceConsole.weakcommands[self][command] = func
end --- Unregister a chatcommand
return true -- @param command Chat command to be unregistered WITHOUT leading "/"
end function AceConsole:UnregisterChatCommand( command )
local name = AceConsole.commands[command]
--- Unregister a chatcommand if name then
-- @param command Chat command to be unregistered WITHOUT leading "/" SlashCmdList[name] = nil
function AceConsole:UnregisterChatCommand( command ) _G["SLASH_" .. name .. "1"] = nil
local name = AceConsole.commands[command] hash_SlashCmdList["/" .. command:upper()] = nil
if name then AceConsole.commands[command] = nil
SlashCmdList[name] = nil end
_G["SLASH_" .. name .. "1"] = nil end
hash_SlashCmdList["/" .. command:upper()] = nil
AceConsole.commands[command] = nil --- Get an iterator over all Chat Commands registered with AceConsole
end -- @return Iterator (pairs) over all commands
end function AceConsole:IterateChatCommands() return pairs(AceConsole.commands) end
--- Get an iterator over all Chat Commands registered with AceConsole
-- @return Iterator (pairs) over all commands local function nils(n, ...)
function AceConsole:IterateChatCommands() return pairs(AceConsole.commands) end if n>1 then
return nil, nils(n-1, ...)
elseif n==1 then
local function nils(n, ...) return nil, ...
if n>1 then else
return nil, nils(n-1, ...) return ...
elseif n==1 then end
return nil, ... end
else
return ...
end --- Retreive one or more space-separated arguments from a string.
end -- Treats quoted strings and itemlinks as non-spaced.
-- @param str The raw argument string
-- @param numargs How many arguments to get (default 1)
--- Retreive one or more space-separated arguments from a string. -- @param startpos Where in the string to start scanning (default 1)
-- Treats quoted strings and itemlinks as non-spaced. -- @return Returns arg1, arg2, ..., nextposition\\
-- @param string The raw argument string -- Missing arguments will be returned as nils. 'nextposition' is returned as 1e9 at the end of the string.
-- @param numargs How many arguments to get (default 1) function AceConsole:GetArgs(str, numargs, startpos)
-- @param startpos Where in the string to start scanning (default 1) numargs = numargs or 1
-- @return Returns arg1, arg2, ..., nextposition\\ startpos = max(startpos or 1, 1)
-- Missing arguments will be returned as nils. 'nextposition' is returned as 1e9 at the end of the string.
function AceConsole:GetArgs(str, numargs, startpos) local pos=startpos
numargs = numargs or 1
startpos = max(startpos or 1, 1) -- find start of new arg
pos = strfind(str, "[^ ]", pos)
local pos=startpos if not pos then -- whoops, end of string
return nils(numargs, 1e9)
-- find start of new arg end
pos = strfind(str, "[^ ]", pos)
if not pos then -- whoops, end of string if numargs<1 then
return nils(numargs, 1e9) return pos
end end
if numargs<1 then -- quoted or space separated? find out which pattern to use
return pos local delim_or_pipe
end local ch = strsub(str, pos, pos)
if ch=='"' then
-- quoted or space separated? find out which pattern to use pos = pos + 1
local delim_or_pipe delim_or_pipe='([|"])'
local ch = strsub(str, pos, pos) elseif ch=="'" then
if ch=='"' then pos = pos + 1
pos = pos + 1 delim_or_pipe="([|'])"
delim_or_pipe='([|"])' else
elseif ch=="'" then delim_or_pipe="([| ])"
pos = pos + 1 end
delim_or_pipe="([|'])"
else startpos = pos
delim_or_pipe="([| ])"
end while true do
-- find delimiter or hyperlink
startpos = pos local _
pos,_,ch = strfind(str, delim_or_pipe, pos)
while true do
-- find delimiter or hyperlink if not pos then break end
local ch,_
pos,_,ch = strfind(str, delim_or_pipe, pos) if ch=="|" then
-- some kind of escape
if not pos then break end
if strsub(str,pos,pos+1)=="|H" then
if ch=="|" then -- It's a |H....|hhyper link!|h
-- some kind of escape pos=strfind(str, "|h", pos+2) -- first |h
if not pos then break end
if strsub(str,pos,pos+1)=="|H" then
-- It's a |H....|hhyper link!|h pos=strfind(str, "|h", pos+2) -- second |h
pos=strfind(str, "|h", pos+2) -- first |h if not pos then break end
if not pos then break end elseif strsub(str,pos, pos+1) == "|T" then
-- It's a |T....|t texture
pos=strfind(str, "|h", pos+2) -- second |h pos=strfind(str, "|t", pos+2)
if not pos then break end if not pos then break end
elseif strsub(str,pos, pos+1) == "|T" then end
-- It's a |T....|t texture
pos=strfind(str, "|t", pos+2) pos=pos+2 -- skip past this escape (last |h if it was a hyperlink)
if not pos then break end
end else
-- found delimiter, done with this arg
pos=pos+2 -- skip past this escape (last |h if it was a hyperlink) return strsub(str, startpos, pos-1), AceConsole:GetArgs(str, numargs-1, pos+1)
end
else
-- found delimiter, done with this arg end
return strsub(str, startpos, pos-1), AceConsole:GetArgs(str, numargs-1, pos+1)
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 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) --- embedding and embed handling
end
local mixins = {
"Print",
--- embedding and embed handling "Printf",
"RegisterChatCommand",
local mixins = { "UnregisterChatCommand",
"Print", "GetArgs",
"Printf", }
"RegisterChatCommand",
"UnregisterChatCommand", -- Embeds AceConsole into the target object making the functions from the mixins list available on target:..
"GetArgs", -- @param target target object to embed AceBucket in
} function AceConsole:Embed( target )
for k, v in pairs( mixins ) do
-- Embeds AceConsole into the target object making the functions from the mixins list available on target:.. target[v] = self[v]
-- @param target target object to embed AceBucket in end
function AceConsole:Embed( target ) self.embeds[target] = true
for k, v in pairs( mixins ) do return target
target[v] = self[v] end
end
self.embeds[target] = true function AceConsole:OnEmbedEnable( target )
return target if AceConsole.weakcommands[target] then
end for command, func in pairs( AceConsole.weakcommands[target] ) do
target:RegisterChatCommand( command, func, false, true ) -- nonpersisting and silent registry
function AceConsole:OnEmbedEnable( target ) end
if AceConsole.weakcommands[target] then end
for command, func in pairs( AceConsole.weakcommands[target] ) do end
target:RegisterChatCommand( command, func, false, true ) -- nonpersisting and silent registry
end function AceConsole:OnEmbedDisable( target )
end if AceConsole.weakcommands[target] then
end 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?
function AceConsole:OnEmbedDisable( target ) end
if AceConsole.weakcommands[target] then end
for command, func in pairs( AceConsole.weakcommands[target] ) do end
target:UnregisterChatCommand( command ) -- TODO: this could potentially unregister a command from another application in case of command conflicts. Do we care?
end for addon in pairs(AceConsole.embeds) do
end AceConsole:Embed(addon)
end end
for addon in pairs(AceConsole.embeds) do
AceConsole:Embed(addon)
end
+3 -3
View File
@@ -1,4 +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/ <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"> ..\FrameXML\UI.xsd">
<Script file="AceConsole-3.0.lua"/> <Script file="AceConsole-3.0.lua"/>
</Ui> </Ui>
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -1,4 +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/ <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"> ..\FrameXML\UI.xsd">
<Script file="AceDB-3.0.lua"/> <Script file="AceDB-3.0.lua"/>
</Ui> </Ui>
+456 -420
View File
@@ -1,420 +1,456 @@
--- AceDBOptions-3.0 provides a universal AceConfig options screen for managing AceDB-3.0 profiles. --- AceDBOptions-3.0 provides a universal AceConfig options screen for managing AceDB-3.0 profiles.
-- @class file -- @class file
-- @name AceDBOptions-3.0 -- @name AceDBOptions-3.0
-- @release $Id: AceDBOptions-3.0.lua 895 2009-12-06 16:28:55Z nevcairiel $ -- @release $Id$
local ACEDBO_MAJOR, ACEDBO_MINOR = "AceDBOptions-3.0", 11 local ACEDBO_MAJOR, ACEDBO_MINOR = "AceDBOptions-3.0", 15
local AceDBOptions, oldminor = LibStub:NewLibrary(ACEDBO_MAJOR, ACEDBO_MINOR) local AceDBOptions = LibStub:NewLibrary(ACEDBO_MAJOR, ACEDBO_MINOR)
if not AceDBOptions then return end -- No upgrade needed if not AceDBOptions then return end -- No upgrade needed
-- Lua APIs -- Lua APIs
local pairs, next = pairs, next local pairs, next = pairs, next
-- WoW APIs -- WoW APIs
local UnitClass = UnitClass local UnitClass = UnitClass
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded AceDBOptions.optionTables = AceDBOptions.optionTables or {}
-- List them here for Mikk's FindGlobals script AceDBOptions.handlers = AceDBOptions.handlers or {}
-- GLOBALS: NORMAL_FONT_COLOR_CODE, FONT_COLOR_CODE_CLOSE
--[[
AceDBOptions.optionTables = AceDBOptions.optionTables or {} Localization of AceDBOptions-3.0
AceDBOptions.handlers = AceDBOptions.handlers or {} ]]
--[[ local L = {
Localization of AceDBOptions-3.0 choose = "Existing Profiles",
]] choose_desc = "You can either create a new profile by entering a name in the editbox, or choose one of the already existing profiles.",
choose_sub = "Select one of your currently available profiles.",
local L = { copy = "Copy From",
default = "Default", copy_desc = "Copy the settings from one existing profile into the currently active profile.",
intro = "You can change the active database profile, so you can have different settings for every character.", current = "Current Profile:",
reset_desc = "Reset the current profile back to its default values, in case your configuration is broken, or you simply want to start over.", default = "Default",
reset = "Reset Profile", delete = "Delete a Profile",
reset_sub = "Reset the current profile to the default", delete_confirm = "Are you sure you want to delete the selected profile?",
choose_desc = "You can either create a new profile by entering a name in the editbox, or choose one of the already exisiting profiles.", delete_desc = "Delete existing and unused profiles from the database to save space, and cleanup the SavedVariables file.",
new = "New", delete_sub = "Deletes a profile from the database.",
new_sub = "Create a new empty profile.", intro = "You can change the active database profile, so you can have different settings for every character.",
choose = "Existing Profiles", new = "New",
choose_sub = "Select one of your currently available profiles.", new_sub = "Create a new empty profile.",
copy_desc = "Copy the settings from one existing profile into the currently active profile.", profiles = "Profiles",
copy = "Copy From", profiles_sub = "Manage Profiles",
delete_desc = "Delete existing and unused profiles from the database to save space, and cleanup the SavedVariables file.", reset = "Reset Profile",
delete = "Delete a Profile", reset_desc = "Reset the current profile back to its default values, in case your configuration is broken, or you simply want to start over.",
delete_sub = "Deletes a profile from the database.", reset_sub = "Reset the current profile to the default",
delete_confirm = "Are you sure you want to delete the selected profile?", }
profiles = "Profiles",
profiles_sub = "Manage Profiles", local LOCALE = GetLocale()
current = "Current Profile:", if LOCALE == "deDE" then
} L["choose"] = "Vorhandene Profile"
L["choose_desc"] = "Du kannst ein neues Profil erstellen, indem du einen neuen Namen in der Eingabebox 'Neu' eingibst, oder wähle eines der vorhandenen Profile aus."
local LOCALE = GetLocale() L["choose_sub"] = "Wählt ein bereits vorhandenes Profil aus."
if LOCALE == "deDE" then L["copy"] = "Kopieren von..."
L["default"] = "Standard" L["copy_desc"] = "Kopiere die Einstellungen von einem vorhandenen Profil in das aktive Profil."
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["current"] = "Aktuelles Profil:"
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["default"] = "Standard"
L["reset"] = "Profil zur\195\188cksetzen" L["delete"] = "Profil löschen"
L["reset_sub"] = "Das aktuelle Profil auf Standard zur\195\188cksetzen." L["delete_confirm"] = "Willst du das ausgewählte Profil wirklich löschen?"
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["delete_desc"] = "Lösche vorhandene oder unbenutzte Profile aus der Datenbank, um Platz zu sparen und die SavedVariables-Datei 'sauber' zu halten."
L["new"] = "Neu" L["delete_sub"] = "Löscht ein Profil aus der Datenbank."
L["new_sub"] = "Ein neues Profil erstellen." L["intro"] = "Hier kannst du das aktive Datenbankprofil ändern, damit du verschiedene Einstellungen für jeden Charakter erstellen kannst, wodurch eine sehr flexible Konfiguration möglich wird."
L["choose"] = "Vorhandene Profile" L["new"] = "Neu"
L["choose_sub"] = "W\195\164hlt ein bereits vorhandenes Profil aus." L["new_sub"] = "Ein neues Profil erstellen."
L["copy_desc"] = "Kopiere die Einstellungen von einem vorhandenen Profil in das aktive Profil." L["profiles"] = "Profile"
L["copy"] = "Kopieren von..." L["profiles_sub"] = "Profile verwalten"
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["reset"] = "Profil zurücksetzen"
L["delete"] = "Profil l\195\182schen" L["reset_desc"] = "Setzt das momentane Profil auf Standardwerte zurück, für den Fall, dass mit der Konfiguration etwas schief lief oder weil du einfach neu starten willst."
L["delete_sub"] = "L\195\182scht ein Profil aus der Datenbank." L["reset_sub"] = "Das aktuelle Profil auf Standard zurücksetzen."
L["delete_confirm"] = "Willst du das ausgew\195\164hlte Profil wirklich l\195\182schen?" elseif LOCALE == "frFR" then
L["profiles"] = "Profile" L["choose"] = "Profils existants"
L["profiles_sub"] = "Profile verwalten" L["choose_desc"] = "Vous pouvez créer un nouveau profil en entrant un nouveau nom dans la boîte de saisie, ou en choississant un des profils déjà existants."
--L["current"] = "Current Profile:" L["choose_sub"] = "Permet de choisir un des profils déjà disponibles."
elseif LOCALE == "frFR" then L["copy"] = "Copier à partir de"
L["default"] = "D\195\169faut" L["copy_desc"] = "Copie les paramètres d'un profil déjà existant dans le profil actuellement actif."
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["current"] = "Profil actuel :"
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["default"] = "Défaut"
L["reset"] = "R\195\169initialiser le profil" L["delete"] = "Supprimer un profil"
L["reset_sub"] = "R\195\169initialise le profil actuel avec les param\195\168tres par d\195\169faut." L["delete_confirm"] = "Etes-vous sûr de vouloir supprimer le profil sélectionné ?"
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["delete_desc"] = "Supprime les profils existants inutilisés de la base de données afin de gagner de la place et de nettoyer le fichier SavedVariables."
L["new"] = "Nouveau" L["delete_sub"] = "Supprime un profil de la base de données."
L["new_sub"] = "Cr\195\169\195\169e un nouveau profil vierge." L["intro"] = "Vous pouvez changer le profil actuel afin d'avoir des paramètres différents pour chaque personnage, permettant ainsi d'avoir une configuration très flexible."
L["choose"] = "Profils existants" L["new"] = "Nouveau"
L["choose_sub"] = "Permet de choisir un des profils d\195\169j\195\160 disponibles." L["new_sub"] = "Créée un nouveau profil vierge."
L["copy_desc"] = "Copie les param\195\168tres d'un profil d\195\169j\195\160 existant dans le profil actuellement actif." L["profiles"] = "Profils"
L["copy"] = "Copier \195\160 partir de" L["profiles_sub"] = "Gestion des profils"
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["reset"] = "Réinitialiser le profil"
L["delete"] = "Supprimer un profil" L["reset_desc"] = "Réinitialise le profil actuel au cas où votre configuration est corrompue ou si vous voulez tout simplement faire table rase."
L["delete_sub"] = "Supprime un profil de la base de donn\195\169es." L["reset_sub"] = "Réinitialise le profil actuel avec les paramètres par défaut."
L["delete_confirm"] = "Etes-vous s\195\187r de vouloir supprimer le profil s\195\169lectionn\195\169 ?" elseif LOCALE == "koKR" then
L["profiles"] = "Profils" L["choose"] = "기존 프로필"
L["profiles_sub"] = "Gestion des profils" L["choose_desc"] = "편집 상자에 이름을 입력하여 새로운 프로필을 만들거나 이미 존재하는 프로필 중 하나를 선택할 수 있습니다."
--L["current"] = "Current Profile:" L["choose_sub"] = "현재 이용할 수 있는 프로필 중 하나를 선택합니다."
elseif LOCALE == "koKR" then L["copy"] = "복사해 올 프로필"
L["default"] = "본값" L["copy_desc"] = "존 프로필의 설정을 현재 활성화된 프로필로 복사합니다."
L["intro"] = "모든 캐릭터의 다양한 설정과 사용중인 데이터베이스 프로필, 어느것이던지 매우 다루기 쉽게 바꿀수 있습니다." L["current"] = "현재 프로필:"
L["reset_desc"] = "단순히 다시 새롭게 구성을 원하는 경우, 현재 프로필을 기본값으로 초기화 합니다." L["default"] = "기본값"
L["reset"] = "프로필 초기화" L["delete"] = "프로필 삭제"
L["reset_sub"] = "현재의 프로필을 기본값으로 초기화 합니다" L["delete_confirm"] = "선택한 프로필을 삭제하시겠습니까?"
L["choose_desc"] = "새로운 이름을 입력하거나, 이미 있는 프로필중 하나를 선택하여 새로운 프로필을 만들 수 있습니다." L["delete_desc"] = "데이터베이스에서 기존 프로필과 사용하지 않는 프로필을 삭제하여 공간을 절약하고 SavedVariables 파일을 정리합니다."
L["new"] = "새로운 프로필" L["delete_sub"] = "데이터베이스에서 프로필을 삭제합니다."
L["new_sub"] = "새로운 프로필을 만듭니다." L["intro"] = "활성 데이터베이스 프로필을 변경할 수 있으며, 모든 캐릭터마다 서로 다른 설정을 지정할 수 있습니다."
L["choose"] = "프로필 선택" L["new"] = "새로운 프로필"
L["choose_sub"] = "당신이 현재 이용할수 있는 프로필을 선택합니다." L["new_sub"] = "비어 있는 프로필을 새로 만듭니다."
L["copy_desc"] = "현재 사용중인 프로필에, 선택한 프로필의 설정을 복사합니다." L["profiles"] = "프로필"
L["copy"] = "복사" L["profiles_sub"] = "프로필 관리"
L["delete_desc"] = "데이터베이스에 사용중이거나 저장된 프로파일 삭제로 SavedVariables 파일의 정리와 공간 절약이 됩니다." L["reset"] = "프로필 재설정"
L["delete"] = "프로필 삭제" L["reset_desc"] = "구성이 손상되었거나 처음부터 다시 시작하고 싶은 경우 현재 프로필을 기본값으로 재설정하세요."
L["delete_sub"] = "데이터베이스의 프로필을 삭제합니다." L["reset_sub"] = "현재 프로필을 기본값으로 재설정합니다"
L["delete_confirm"] = "정말로 선택한 프로필의 삭제를 원하십니까?" elseif LOCALE == "esES" or LOCALE == "esMX" then
L["profiles"] = "프로필" L["choose"] = "Perfiles existentes"
L["profiles_sub"] = "프로필 설정" L["choose_desc"] = "Puedes crear un nuevo perfil introduciendo un nombre en el recuadro o puedes seleccionar un perfil de los ya existentes."
--L["current"] = "Current Profile:" L["choose_sub"] = "Selecciona uno de los perfiles disponibles."
elseif LOCALE == "esES" or LOCALE == "esMX" then L["copy"] = "Copiar de"
L["default"] = "Por defecto" L["copy_desc"] = "Copia los ajustes de un perfil existente al perfil actual."
L["intro"] = "Puedes cambiar el perfil activo de tal manera que cada personaje tenga diferentes configuraciones." L["current"] = "Perfil actual:"
L["reset_desc"] = "Reinicia el perfil actual a los valores por defectos, en caso de que se haya estropeado la configuración o quieras volver a empezar de nuevo." L["default"] = "Por defecto"
L["reset"] = "Reiniciar Perfil" L["delete"] = "Borrar un Perfil"
L["reset_sub"] = "Reinicar el perfil actual al de por defecto" L["delete_confirm"] = "¿Estas seguro que quieres borrar el perfil seleccionado?"
L["choose_desc"] = "Puedes crear un nuevo perfil introduciendo un nombre en el recuadro o puedes seleccionar un perfil de los ya existentes." L["delete_desc"] = "Borra los perfiles existentes y sin uso de la base de datos para ganar espacio y limpiar el archivo SavedVariables."
L["new"] = "Nuevo" L["delete_sub"] = "Borra un perfil de la base de datos."
L["new_sub"] = "Crear un nuevo perfil vacio." L["intro"] = "Puedes cambiar el perfil activo de tal manera que cada personaje tenga diferentes configuraciones."
L["choose"] = "Perfiles existentes" L["new"] = "Nuevo"
L["choose_sub"] = "Selecciona uno de los perfiles disponibles." L["new_sub"] = "Crear un nuevo perfil vacio."
L["copy_desc"] = "Copia los ajustes de un perfil existente al perfil actual." L["profiles"] = "Perfiles"
L["copy"] = "Copiar de" L["profiles_sub"] = "Manejar Perfiles"
L["delete_desc"] = "Borra los perfiles existentes y sin uso de la base de datos para ganar espacio y limpiar el archivo SavedVariables." L["reset"] = "Reiniciar Perfil"
L["delete"] = "Borrar un Perfil" L["reset_desc"] = "Reinicia el perfil actual a los valores por defectos, en caso de que se haya estropeado la configuración o quieras volver a empezar de nuevo."
L["delete_sub"] = "Borra un perfil de la base de datos." L["reset_sub"] = "Reinicar el perfil actual al de por defecto"
L["delete_confirm"] = "¿Estas seguro que quieres borrar el perfil seleccionado?" elseif LOCALE == "zhTW" then
L["profiles"] = "Perfiles" L["choose"] = "現有的設定檔"
L["profiles_sub"] = "Manejar Perfiles" L["choose_desc"] = "您可以在文字方塊內輸入名字以建立新的設定檔,或是選擇一個現有的設定檔使用。"
--L["current"] = "Current Profile:" L["choose_sub"] = "從當前可用的設定檔裡面選擇一個。"
elseif LOCALE == "zhTW" then L["copy"] = "複製自"
L["default"] = "預設" L["copy_desc"] = "從一個現有的設定檔,將設定複製到現在使用中的設定檔。"
L["intro"] = "你可以選擇一個活動的資料設定檔,這樣你的每個角色就可以擁有不同的設定值,可以給你的插件設定帶來極大的靈活性。" L["current"] = "目前設定檔:"
L["reset_desc"] = "將當前的設定檔恢復到它的預設值,用於你的設定檔損壞,或者你只是想重來的情況。" L["default"] = "預設"
L["reset"] = "重置設定檔" L["delete"] = "刪除一個設定檔"
L["reset_sub"] = "將當前的設定檔恢復為預設值" L["delete_confirm"] = "確定要刪除所選擇的設定檔嗎?"
L["choose_desc"] = "你可以通過在文本框內輸入一個名字創立一個新的設定檔,也可以選擇一個已經存在的設定檔" L["delete_desc"] = "從資料庫裡刪除不再使用的設定檔,以節省空間,並且清理 SavedVariables 檔案"
L["new"] = "新建" L["delete_sub"] = "從資料庫裡刪除一個設定檔。"
L["new_sub"] = "新建一個空的設定" L["intro"] = "您可以從資料庫中選擇一個設定檔來使用,如此就可以讓每個角色使用不同的設定。"
L["choose"] = "現有的設定檔" L["new"] = "新建"
L["choose_sub"] = "從當前可用的設定檔裏面選擇一個" L["new_sub"] = "新建一個空的設定檔"
L["copy_desc"] = "從當前某個已保存的設定檔複製到當前正使用的設定檔。" L["profiles"] = "設定檔"
L["copy"] = "複製自" L["profiles_sub"] = "管理設定檔"
L["delete_desc"] = "從資料庫裏刪除不再使用的設定檔,以節省空間,並且清理SavedVariables檔。" L["reset"] = "重置設定檔"
L["delete"] = "刪除一個設定檔" L["reset_desc"] = "將現用的設定檔重置為預設值;用於設定檔損壞,或者單純想要重來的情況。"
L["delete_sub"] = "從資料庫裏刪除一個設定檔。" L["reset_sub"] = "將目前的設定檔重置為預設值"
L["delete_confirm"] = "你確定要刪除所選擇的設定檔嗎?" elseif LOCALE == "zhCN" then
L["profiles"] = "設定檔" L["choose"] = "现有的配置文件"
L["profiles_sub"] = "管理設定檔" L["choose_desc"] = "你可以通过在文本框内输入一个名字创立一个新的配置文件,也可以选择一个已经存在的配置文件。"
--L["current"] = "Current Profile:" L["choose_sub"] = "从当前可用的配置文件里面选择一个。"
elseif LOCALE == "zhCN" then L["copy"] = "复制自"
L["default"] = "默认" L["copy_desc"] = "从当前某个已保存的配置文件复制到当前正使用的配置文件。"
L["intro"] = "你可以选择一个活动的数据配置文件,这样你的每个角色就可以拥有不同的设置值,可以给你的插件配置带来极大的灵活性。" L["current"] = "当前配置文件:"
L["reset_desc"] = "将当前的配置文件恢复到它的默认值,用于你的配置文件损坏,或者你只是想重来的情况。" L["default"] = "默认"
L["reset"] = "重置配置文件" L["delete"] = "删除一个配置文件"
L["reset_sub"] = "将当前的配置文件恢复为默认值" L["delete_confirm"] = "你确定要删除所选择的配置文件么?"
L["choose_desc"] = "你可以通过在文本框内输入一个名字创立一个新的配置文件,也可以选择一个已经存在的配置文件。" L["delete_desc"] = "从数据库里删除不再使用的配置文件,以节省空间,并且清理SavedVariables文件。"
L["new"] = "新建" L["delete_sub"] = "从数据库里删除一个配置文件。"
L["new_sub"] = "新建一个空的配置文件" L["intro"] = "你可以选择一个活动的数据配置文件,这样你的每个角色就可以拥有不同的设置值,可以给你的插件配置带来极大的灵活性"
L["choose"] = "现有的配置文件" L["new"] = "新建"
L["choose_sub"] = "从当前可用的配置文件里面选择一个" L["new_sub"] = "新建一个空的配置文件"
L["copy_desc"] = "从当前某个已保存的配置文件复制到当前正使用的配置文件。" L["profiles"] = "配置文件"
L["copy"] = "复制自" L["profiles_sub"] = "管理配置文件"
L["delete_desc"] = "从数据库里删除不再使用的配置文件,以节省空间,并且清理SavedVariables文件。" L["reset"] = "重置配置文件"
L["delete"] = "删除一个配置文件" L["reset_desc"] = "将当前的配置文件恢复到它的默认值,用于你的配置文件损坏,或者你只是想重来的情况。"
L["delete_sub"] = "从数据库里删除一个配置文件。" L["reset_sub"] = "将当前的配置文件恢复为默认值"
L["delete_confirm"] = "你确定要删除所选择的配置文件么?" elseif LOCALE == "ruRU" then
L["profiles"] = "配置文件" L["choose"] = "Существующие профили"
L["profiles_sub"] = "管理配置文件" L["choose_desc"] = "Вы можете создать новый профиль, введя название в поле ввода, или выбрать один из уже существующих профилей."
--L["current"] = "Current Profile:" L["choose_sub"] = "Выбор одного из уже доступных профилей."
elseif LOCALE == "ruRU" then L["copy"] = "Скопировать из"
L["default"] = "По умолчанию" L["copy_desc"] = "Копирование настроек из выбранного профиля в активный."
L["intro"] = "Изменяя активный профиль, вы можете задать различные настройки модификаций для каждого персонажа." L["current"] = "Текущий профиль:"
L["reset_desc"] = "Если ваша конфигурации испорчена или если вы хотите настроить всё заново - сбросьте текущий профиль на стандартные значения." L["default"] = "По умолчанию"
L["reset"] = "Сброс профиля" L["delete"] = "Удалить профиль"
L["reset_sub"] = "Сброс текущего профиля на стандартный" L["delete_confirm"] = "Вы уверены, что хотите удалить выбранный профиль?"
L["choose_desc"] = "Вы можете создать новый профиль, введя название в поле ввода, или выбрать один из уже существующих профилей." L["delete_desc"] = "Удаление существующего и неиспользуемого профиля из базы данных для сохранения места, и очистка файла SavedVariables."
L["new"] = "Новый" L["delete_sub"] = "Удаление профиля из базы данных."
L["new_sub"] = "Создать новый чистый профиль" L["intro"] = "Изменяя активный профиль, Вы можете задать разные настройки для каждого персонажа."
L["choose"] = "Существующие профили" L["new"] = "Новый"
L["choose_sub"] = "Выбор одиного из уже доступных профилей" L["new_sub"] = "Создание нового чистого профиля."
L["copy_desc"] = "Скопировать настройки из выбранного профиля в активный." L["profiles"] = "Профили"
L["copy"] = "Скопировать из" L["profiles_sub"] = "Управление профилями"
L["delete_desc"] = "Удалить существующий и неиспользуемый профиль из БД для сохранения места, и очистить SavedVariables файл." L["reset"] = "Сбросить профиль"
L["delete"] = "Удалить профиль" L["reset_desc"] = "Сброс текущего профиля к стандартным настройкам, если Ваша конфигурация испорчена или Вы хотите настроить все заново."
L["delete_sub"] = "Удаление профиля из БД" L["reset_sub"] = "Сброс текущего профиля на стандартный"
L["delete_confirm"] = "Вы уверены, что вы хотите удалить выбранный профиль?" elseif LOCALE == "itIT" then
L["profiles"] = "Профили" L["choose"] = "Profili Esistenti"
L["profiles_sub"] = "Управление профилями" L["choose_desc"] = "Puoi creare un nuovo profilo digitando il nome della casella di testo, oppure scegliendone uno tra i profili già esistenti."
--L["current"] = "Current Profile:" L["choose_sub"] = "Seleziona uno dei profili attualmente disponibili."
end L["copy"] = "Copia Da"
L["copy_desc"] = "Copia le impostazioni da un profilo esistente nel profilo attivo in questo momento."
local defaultProfiles L["current"] = "Profilo Attivo:"
local tmpprofiles = {} L["default"] = "Predefinito"
L["delete"] = "Cancella un Profilo"
-- Get a list of available profiles for the specified database. L["delete_confirm"] = "Sei sicuro di voler cancellare il profilo selezionato?"
-- You can specify which profiles to include/exclude in the list using the two boolean parameters listed below. L["delete_desc"] = "Cancella i profili non utilizzati dal database per risparmiare spazio e mantenere puliti i file di configurazione SavedVariables."
-- @param db The db object to retrieve the profiles from L["delete_sub"] = "Cancella un profilo dal Database."
-- @param common If true, getProfileList will add the default profiles to the return list, even if they have not been created yet L["intro"] = "Puoi cambiare il profilo attivo, in modo da usare impostazioni diverse per ogni personaggio."
-- @param nocurrent If true, then getProfileList will not display the current profile in the list L["new"] = "Nuovo"
-- @return Hashtable of all profiles with the internal name as keys and the display name as value. L["new_sub"] = "Crea un nuovo profilo vuoto."
local function getProfileList(db, common, nocurrent) L["profiles"] = "Profili"
local profiles = {} L["profiles_sub"] = "Gestisci Profili"
L["reset"] = "Reimposta Profilo"
-- copy existing profiles into the table L["reset_desc"] = "Riporta il tuo profilo attivo alle sue impostazioni predefinite, nel caso in cui la tua configurazione si sia corrotta, o semplicemente tu voglia re-inizializzarla."
local currentProfile = db:GetCurrentProfile() L["reset_sub"] = "Reimposta il profilo ai suoi valori predefiniti."
for i,v in pairs(db:GetProfiles(tmpprofiles)) do elseif LOCALE == "ptBR" then
if not (nocurrent and v == currentProfile) then L["choose"] = "Perfis Existentes"
profiles[v] = v L["choose_desc"] = "Você pode tanto criar um perfil novo tanto digitando um nome na caixa de texto, quanto escolher um dos perfis já existentes."
end L["choose_sub"] = "Selecione um de seus perfis atualmente disponíveis."
end L["copy"] = "Copiar De"
L["copy_desc"] = "Copia as definições de um perfil existente no perfil atualmente ativo."
-- add our default profiles to choose from ( or rename existing profiles) L["current"] = "Perfil Autal:"
for k,v in pairs(defaultProfiles) do L["default"] = "Padrão"
if (common or profiles[k]) and not (nocurrent and k == currentProfile) then L["delete"] = "Remover um Perfil"
profiles[k] = v L["delete_confirm"] = "Tem certeza que deseja remover o perfil selecionado?"
end L["delete_desc"] = "Remove perfis existentes e inutilizados do banco de dados para economizar espaço, e limpar o arquivo SavedVariables."
end L["delete_sub"] = "Remove um perfil do banco de dados."
L["intro"] = "Você pode alterar o perfil do banco de dados ativo, para que possa ter definições diferentes para cada personagem."
return profiles L["new"] = "Novo"
end L["new_sub"] = "Cria um novo perfil vazio."
L["profiles"] = "Perfis"
--[[ L["profiles_sub"] = "Gerenciar Perfis"
OptionsHandlerPrototype L["reset"] = "Resetar Perfil"
prototype class for handling the options in a sane way L["reset_desc"] = "Reseta o perfil atual para os valores padrões, no caso de sua configuração estar quebrada, ou simplesmente se deseja começar novamente."
]] L["reset_sub"] = "Resetar o perfil atual ao padrão"
local OptionsHandlerPrototype = {} end
--[[ Reset the profile ]] local defaultProfiles
function OptionsHandlerPrototype:Reset() local tmpprofiles = {}
self.db:ResetProfile()
end -- Get a list of available profiles for the specified database.
-- You can specify which profiles to include/exclude in the list using the two boolean parameters listed below.
--[[ Set the profile to value ]] -- @param db The db object to retrieve the profiles from
function OptionsHandlerPrototype:SetProfile(info, value) -- @param common If true, getProfileList will add the default profiles to the return list, even if they have not been created yet
self.db:SetProfile(value) -- @param nocurrent If true, then getProfileList will not display the current profile in the list
end -- @return Hashtable of all profiles with the internal name as keys and the display name as value.
local function getProfileList(db, common, nocurrent)
--[[ returns the currently active profile ]] local profiles = {}
function OptionsHandlerPrototype:GetCurrentProfile()
return self.db:GetCurrentProfile() -- copy existing profiles into the table
end local currentProfile = db:GetCurrentProfile()
for i,v in pairs(db:GetProfiles(tmpprofiles)) do
--[[ if not (nocurrent and v == currentProfile) then
List all active profiles profiles[v] = v
you can control the output with the .arg variable end
currently four modes are supported end
(empty) - return all available profiles -- add our default profiles to choose from ( or rename existing profiles)
"nocurrent" - returns all available profiles except the currently active profile for k,v in pairs(defaultProfiles) do
"common" - returns all avaialble profiles + some commonly used profiles ("char - realm", "realm", "class", "Default") if (common or profiles[k]) and not (nocurrent and k == currentProfile) then
"both" - common except the active profile profiles[k] = v
]] end
function OptionsHandlerPrototype:ListProfiles(info) end
local arg = info.arg
local profiles return profiles
if arg == "common" and not self.noDefaultProfiles then end
profiles = getProfileList(self.db, true, nil)
elseif arg == "nocurrent" then --[[
profiles = getProfileList(self.db, nil, true) OptionsHandlerPrototype
elseif arg == "both" then -- currently not used prototype class for handling the options in a sane way
profiles = getProfileList(self.db, (not self.noDefaultProfiles) and true, true) ]]
else local OptionsHandlerPrototype = {}
profiles = getProfileList(self.db)
end --[[ Reset the profile ]]
function OptionsHandlerPrototype:Reset()
return profiles self.db:ResetProfile()
end end
function OptionsHandlerPrototype:HasNoProfiles(info) --[[ Set the profile to value ]]
local profiles = self:ListProfiles(info) function OptionsHandlerPrototype:SetProfile(info, value)
return ((not next(profiles)) and true or false) self.db:SetProfile(value)
end end
--[[ Copy a profile ]] --[[ returns the currently active profile ]]
function OptionsHandlerPrototype:CopyProfile(info, value) function OptionsHandlerPrototype:GetCurrentProfile()
self.db:CopyProfile(value) return self.db:GetCurrentProfile()
end end
--[[ Delete a profile from the db ]] --[[
function OptionsHandlerPrototype:DeleteProfile(info, value) List all active profiles
self.db:DeleteProfile(value) you can control the output with the .arg variable
end currently four modes are supported
--[[ fill defaultProfiles with some generic values ]] (empty) - return all available profiles
local function generateDefaultProfiles(db) "nocurrent" - returns all available profiles except the currently active profile
defaultProfiles = { "common" - returns all avaialble profiles + some commonly used profiles ("char - realm", "realm", "class", "Default")
["Default"] = L["default"], "both" - common except the active profile
[db.keys.char] = db.keys.char, ]]
[db.keys.realm] = db.keys.realm, function OptionsHandlerPrototype:ListProfiles(info)
[db.keys.class] = UnitClass("player") local arg = info.arg
} local profiles
end if arg == "common" and not self.noDefaultProfiles then
profiles = getProfileList(self.db, true, nil)
--[[ create and return a handler object for the db, or upgrade it if it already existed ]] elseif arg == "nocurrent" then
local function getOptionsHandler(db, noDefaultProfiles) profiles = getProfileList(self.db, nil, true)
if not defaultProfiles then elseif arg == "both" then -- currently not used
generateDefaultProfiles(db) profiles = getProfileList(self.db, (not self.noDefaultProfiles) and true, true)
end else
profiles = getProfileList(self.db)
local handler = AceDBOptions.handlers[db] or { db = db, noDefaultProfiles = noDefaultProfiles } end
for k,v in pairs(OptionsHandlerPrototype) do return profiles
handler[k] = v end
end
function OptionsHandlerPrototype:HasNoProfiles(info)
AceDBOptions.handlers[db] = handler local profiles = self:ListProfiles(info)
return handler return ((not next(profiles)) and true or false)
end end
--[[ --[[ Copy a profile ]]
the real options table function OptionsHandlerPrototype:CopyProfile(info, value)
]] self.db:CopyProfile(value)
local optionsTable = { end
desc = {
order = 1, --[[ Delete a profile from the db ]]
type = "description", function OptionsHandlerPrototype:DeleteProfile(info, value)
name = L["intro"] .. "\n", self.db:DeleteProfile(value)
}, end
descreset = {
order = 9, --[[ fill defaultProfiles with some generic values ]]
type = "description", local function generateDefaultProfiles(db)
name = L["reset_desc"], defaultProfiles = {
}, ["Default"] = L["default"],
reset = { [db.keys.char] = db.keys.char,
order = 10, [db.keys.realm] = db.keys.realm,
type = "execute", [db.keys.class] = UnitClass("player")
name = L["reset"], }
desc = L["reset_sub"], end
func = "Reset",
}, --[[ create and return a handler object for the db, or upgrade it if it already existed ]]
current = { local function getOptionsHandler(db, noDefaultProfiles)
order = 11, if not defaultProfiles then
type = "description", generateDefaultProfiles(db)
name = function(info) return L["current"] .. " " .. NORMAL_FONT_COLOR_CODE .. info.handler:GetCurrentProfile() .. FONT_COLOR_CODE_CLOSE end, end
width = "default",
}, local handler = AceDBOptions.handlers[db] or { db = db, noDefaultProfiles = noDefaultProfiles }
choosedesc = {
order = 20, for k,v in pairs(OptionsHandlerPrototype) do
type = "description", handler[k] = v
name = "\n" .. L["choose_desc"], end
},
new = { AceDBOptions.handlers[db] = handler
name = L["new"], return handler
desc = L["new_sub"], end
type = "input",
order = 30, --[[
get = false, the real options table
set = "SetProfile", ]]
}, local optionsTable = {
choose = { desc = {
name = L["choose"], order = 1,
desc = L["choose_sub"], type = "description",
type = "select", name = L["intro"] .. "\n",
order = 40, },
get = "GetCurrentProfile", descreset = {
set = "SetProfile", order = 9,
values = "ListProfiles", type = "description",
arg = "common", name = L["reset_desc"],
}, },
copydesc = { reset = {
order = 50, order = 10,
type = "description", type = "execute",
name = "\n" .. L["copy_desc"], name = L["reset"],
}, desc = L["reset_sub"],
copyfrom = { func = "Reset",
order = 60, },
type = "select", current = {
name = L["copy"], order = 11,
desc = L["copy_desc"], type = "description",
get = false, name = function(info) return L["current"] .. " " .. NORMAL_FONT_COLOR_CODE .. info.handler:GetCurrentProfile() .. FONT_COLOR_CODE_CLOSE end,
set = "CopyProfile", width = "default",
values = "ListProfiles", },
disabled = "HasNoProfiles", choosedesc = {
arg = "nocurrent", order = 20,
}, type = "description",
deldesc = { name = "\n" .. L["choose_desc"],
order = 70, },
type = "description", new = {
name = "\n" .. L["delete_desc"], name = L["new"],
}, desc = L["new_sub"],
delete = { type = "input",
order = 80, order = 30,
type = "select", get = false,
name = L["delete"], set = "SetProfile",
desc = L["delete_sub"], },
get = false, choose = {
set = "DeleteProfile", name = L["choose"],
values = "ListProfiles", desc = L["choose_sub"],
disabled = "HasNoProfiles", type = "select",
arg = "nocurrent", order = 40,
confirm = true, get = "GetCurrentProfile",
confirmText = L["delete_confirm"], set = "SetProfile",
}, values = "ListProfiles",
} arg = "common",
},
--- Get/Create a option table that you can use in your addon to control the profiles of AceDB-3.0. copydesc = {
-- @param db The database object to create the options table for. order = 50,
-- @return The options table to be used in AceConfig-3.0 type = "description",
-- @usage name = "\n" .. L["copy_desc"],
-- -- Assuming `options` is your top-level options table and `self.db` is your database: },
-- options.args.profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db) copyfrom = {
function AceDBOptions:GetOptionsTable(db, noDefaultProfiles) order = 60,
local tbl = AceDBOptions.optionTables[db] or { type = "select",
type = "group", name = L["copy"],
name = L["profiles"], desc = L["copy_desc"],
desc = L["profiles_sub"], get = false,
} set = "CopyProfile",
values = "ListProfiles",
tbl.handler = getOptionsHandler(db, noDefaultProfiles) disabled = "HasNoProfiles",
tbl.args = optionsTable arg = "nocurrent",
},
AceDBOptions.optionTables[db] = tbl deldesc = {
return tbl order = 70,
end type = "description",
name = "\n" .. L["delete_desc"],
-- upgrade existing tables },
for db,tbl in pairs(AceDBOptions.optionTables) do delete = {
tbl.handler = getOptionsHandler(db) order = 80,
tbl.args = optionsTable type = "select",
end name = L["delete"],
desc = L["delete_sub"],
get = false,
set = "DeleteProfile",
values = "ListProfiles",
disabled = "HasNoProfiles",
arg = "nocurrent",
confirm = true,
confirmText = L["delete_confirm"],
},
}
--- Get/Create a option table that you can use in your addon to control the profiles of AceDB-3.0.
-- @param db The database object to create the options table for.
-- @return The options table to be used in AceConfig-3.0
-- @usage
-- -- Assuming `options` is your top-level options table and `self.db` is your database:
-- options.args.profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db)
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
+3 -3
View File
@@ -1,4 +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/ <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"> ..\FrameXML\UI.xsd">
<Script file="AceDBOptions-3.0.lua"/> <Script file="AceDBOptions-3.0.lua"/>
</Ui> </Ui>
+126 -126
View File
@@ -1,126 +1,126 @@
--- AceEvent-3.0 provides event registration and secure dispatching. --- AceEvent-3.0 provides event registration and secure dispatching.
-- All dispatching is done using **CallbackHandler-1.0**. AceEvent is a simple wrapper around -- All dispatching is done using **CallbackHandler-1.0**. AceEvent is a simple wrapper around
-- CallbackHandler, and dispatches all game events or addon message to the registrees. -- CallbackHandler, and dispatches all game events or addon message to the registrees.
-- --
-- **AceEvent-3.0** can be embeded into your addon, either explicitly by calling AceEvent:Embed(MyAddon) or by -- **AceEvent-3.0** can be embeded into your addon, either explicitly by calling AceEvent:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object -- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceEvent itself.\\ -- and can be accessed directly, without having to explicitly call AceEvent itself.\\
-- It is recommended to embed AceEvent, otherwise you'll have to specify a custom `self` on all calls you -- It is recommended to embed AceEvent, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceEvent. -- make into AceEvent.
-- @class file -- @class file
-- @name AceEvent-3.0 -- @name AceEvent-3.0
-- @release $Id: AceEvent-3.0.lua 877 2009-11-02 15:56:50Z nevcairiel $ -- @release $Id$
local MAJOR, MINOR = "AceEvent-3.0", 3 local CallbackHandler = LibStub("CallbackHandler-1.0")
local AceEvent = LibStub:NewLibrary(MAJOR, MINOR)
local MAJOR, MINOR = "AceEvent-3.0", 4
if not AceEvent then return end local AceEvent = LibStub:NewLibrary(MAJOR, MINOR)
-- Lua APIs if not AceEvent then return end
local pairs = pairs
-- Lua APIs
local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0") local pairs = pairs
AceEvent.frame = AceEvent.frame or CreateFrame("Frame", "AceEvent30Frame") -- our event frame AceEvent.frame = AceEvent.frame or CreateFrame("Frame", "AceEvent30Frame") -- our event frame
AceEvent.embeds = AceEvent.embeds or {} -- what objects embed this lib AceEvent.embeds = AceEvent.embeds or {} -- what objects embed this lib
-- APIs and registry for blizzard events, using CallbackHandler lib -- APIs and registry for blizzard events, using CallbackHandler lib
if not AceEvent.events then if not AceEvent.events then
AceEvent.events = CallbackHandler:New(AceEvent, AceEvent.events = CallbackHandler:New(AceEvent,
"RegisterEvent", "UnregisterEvent", "UnregisterAllEvents") "RegisterEvent", "UnregisterEvent", "UnregisterAllEvents")
end end
function AceEvent.events:OnUsed(target, eventname) function AceEvent.events:OnUsed(target, eventname)
AceEvent.frame:RegisterEvent(eventname) AceEvent.frame:RegisterEvent(eventname)
end end
function AceEvent.events:OnUnused(target, eventname) function AceEvent.events:OnUnused(target, eventname)
AceEvent.frame:UnregisterEvent(eventname) AceEvent.frame:UnregisterEvent(eventname)
end end
-- APIs and registry for IPC messages, using CallbackHandler lib -- APIs and registry for IPC messages, using CallbackHandler lib
if not AceEvent.messages then if not AceEvent.messages then
AceEvent.messages = CallbackHandler:New(AceEvent, AceEvent.messages = CallbackHandler:New(AceEvent,
"RegisterMessage", "UnregisterMessage", "UnregisterAllMessages" "RegisterMessage", "UnregisterMessage", "UnregisterAllMessages"
) )
AceEvent.SendMessage = AceEvent.messages.Fire AceEvent.SendMessage = AceEvent.messages.Fire
end end
--- embedding and embed handling --- embedding and embed handling
local mixins = { local mixins = {
"RegisterEvent", "UnregisterEvent", "RegisterEvent", "UnregisterEvent",
"RegisterMessage", "UnregisterMessage", "RegisterMessage", "UnregisterMessage",
"SendMessage", "SendMessage",
"UnregisterAllEvents", "UnregisterAllMessages", "UnregisterAllEvents", "UnregisterAllMessages",
} }
--- Register for a Blizzard Event. --- Register for a Blizzard Event.
-- The callback will always be called with the event as the first argument, and if supplied, the `arg` as second argument. -- The callback will be called with the optional `arg` as the first argument (if supplied), and the event name as the second (or first, if no arg was supplied)
-- Any arguments to the event will be passed on after that. -- Any arguments to the event will be passed on after that.
-- @name AceEvent:RegisterEvent -- @name AceEvent:RegisterEvent
-- @class function -- @class function
-- @paramsig event[, callback [, arg]] -- @paramsig event[, callback [, arg]]
-- @param event The event to register for -- @param event The event to register for
-- @param callback The callback function to call when the event is triggered (funcref or method, defaults to a method with the event name) -- @param callback The callback function to call when the event is triggered (funcref or method, defaults to a method with the event name)
-- @param arg An optional argument to pass to the callback function -- @param arg An optional argument to pass to the callback function
--- Unregister an event. --- Unregister an event.
-- @name AceEvent:UnregisterEvent -- @name AceEvent:UnregisterEvent
-- @class function -- @class function
-- @paramsig event -- @paramsig event
-- @param event The event to unregister -- @param event The event to unregister
--- Register for a custom AceEvent-internal message. --- Register for a custom AceEvent-internal message.
-- The callback will always be called with the event as the first argument, and if supplied, the `arg` as second argument. -- The callback will be called with the optional `arg` as the first argument (if supplied), and the event name as the second (or first, if no arg was supplied)
-- Any arguments to the event will be passed on after that. -- Any arguments to the event will be passed on after that.
-- @name AceEvent:RegisterMessage -- @name AceEvent:RegisterMessage
-- @class function -- @class function
-- @paramsig message[, callback [, arg]] -- @paramsig message[, callback [, arg]]
-- @param message The message to register for -- @param message The message to register for
-- @param callback The callback function to call when the message is triggered (funcref or method, defaults to a method with the event name) -- @param callback The callback function to call when the message is triggered (funcref or method, defaults to a method with the event name)
-- @param arg An optional argument to pass to the callback function -- @param arg An optional argument to pass to the callback function
--- Unregister a message --- Unregister a message
-- @name AceEvent:UnregisterMessage -- @name AceEvent:UnregisterMessage
-- @class function -- @class function
-- @paramsig message -- @paramsig message
-- @param message The message to unregister -- @param message The message to unregister
--- Send a message over the AceEvent-3.0 internal message system to other addons registered for this message. --- Send a message over the AceEvent-3.0 internal message system to other addons registered for this message.
-- @name AceEvent:SendMessage -- @name AceEvent:SendMessage
-- @class function -- @class function
-- @paramsig message, ... -- @paramsig message, ...
-- @param message The message to send -- @param message The message to send
-- @param ... Any arguments to the message -- @param ... Any arguments to the message
-- Embeds AceEvent into the target object making the functions from the mixins list available on target:.. -- Embeds AceEvent into the target object making the functions from the mixins list available on target:..
-- @param target target object to embed AceEvent in -- @param target target object to embed AceEvent in
function AceEvent:Embed(target) function AceEvent:Embed(target)
for k, v in pairs(mixins) do for k, v in pairs(mixins) do
target[v] = self[v] target[v] = self[v]
end end
self.embeds[target] = true self.embeds[target] = true
return target return target
end end
-- AceEvent:OnEmbedDisable( target ) -- AceEvent:OnEmbedDisable( target )
-- target (object) - target object that is being disabled -- target (object) - target object that is being disabled
-- --
-- Unregister all events messages etc when the target disables. -- Unregister all events messages etc when the target disables.
-- this method should be called by the target manually or by an addon framework -- this method should be called by the target manually or by an addon framework
function AceEvent:OnEmbedDisable(target) function AceEvent:OnEmbedDisable(target)
target:UnregisterAllEvents() target:UnregisterAllEvents()
target:UnregisterAllMessages() target:UnregisterAllMessages()
end end
-- Script to fire blizzard events into the event listeners -- Script to fire blizzard events into the event listeners
local events = AceEvent.events local events = AceEvent.events
AceEvent.frame:SetScript("OnEvent", function(this, event, ...) AceEvent.frame:SetScript("OnEvent", function(this, event, ...)
events:Fire(event, ...) events:Fire(event, ...)
end) end)
--- Finally: upgrade our old embeds --- Finally: upgrade our old embeds
for target, v in pairs(AceEvent.embeds) do for target, v in pairs(AceEvent.embeds) do
AceEvent:Embed(target) AceEvent:Embed(target)
end end
+3 -3
View File
@@ -1,4 +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/ <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"> ..\FrameXML\UI.xsd">
<Script file="AceEvent-3.0.lua"/> <Script file="AceEvent-3.0.lua"/>
</Ui> </Ui>
File diff suppressed because it is too large Load Diff
+28 -26
View File
@@ -1,26 +1,28 @@
<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/ <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"> ..\FrameXML\UI.xsd">
<Script file="AceGUI-3.0.lua"/> <Script file="AceGUI-3.0.lua"/>
<Script file="widgets\AceGUIWidget-Button.lua"/> <!-- Container -->
<Script file="widgets\AceGUIWidget-CheckBox.lua"/> <Script file="widgets\AceGUIContainer-BlizOptionsGroup.lua"/>
<Script file="widgets\AceGUIWidget-ColorPicker.lua"/> <Script file="widgets\AceGUIContainer-DropDownGroup.lua"/>
<Script file="widgets\AceGUIWidget-DropDownGroup.lua"/> <Script file="widgets\AceGUIContainer-Frame.lua"/>
<Script file="widgets\AceGUIWidget-DropDown.lua"/> <Script file="widgets\AceGUIContainer-InlineGroup.lua"/>
<Script file="widgets\AceGUIWidget-DropDown-Items.lua"/> <Script file="widgets\AceGUIContainer-ScrollFrame.lua"/>
<Script file="widgets\AceGUIWidget-EditBox.lua"/> <Script file="widgets\AceGUIContainer-SimpleGroup.lua"/>
<Script file="widgets\AceGUIWidget-Frame.lua"/> <Script file="widgets\AceGUIContainer-TabGroup.lua"/>
<Script file="widgets\AceGUIWidget-Window.lua"/> <Script file="widgets\AceGUIContainer-TreeGroup.lua"/>
<Script file="widgets\AceGUIWidget-Heading.lua"/> <Script file="widgets\AceGUIContainer-Window.lua"/>
<Script file="widgets\AceGUIWidget-InlineGroup.lua"/> <!-- Widgets -->
<Script file="widgets\AceGUIWidget-Keybinding.lua"/> <Script file="widgets\AceGUIWidget-Button.lua"/>
<Script file="widgets\AceGUIWidget-ScrollFrame.lua"/> <Script file="widgets\AceGUIWidget-CheckBox.lua"/>
<Script file="widgets\AceGUIWidget-SimpleGroup.lua"/> <Script file="widgets\AceGUIWidget-ColorPicker.lua"/>
<Script file="widgets\AceGUIWidget-Slider.lua"/> <Script file="widgets\AceGUIWidget-DropDown.lua"/>
<Script file="widgets\AceGUIWidget-TabGroup.lua"/> <Script file="widgets\AceGUIWidget-DropDown-Items.lua"/>
<Script file="widgets\AceGUIWidget-TreeGroup.lua"/> <Script file="widgets\AceGUIWidget-EditBox.lua"/>
<Script file="widgets\AceGUIWidget-Label.lua"/> <Script file="widgets\AceGUIWidget-Heading.lua"/>
<Script file="widgets\AceGUIWidget-MultiLineEditBox.lua"/> <Script file="widgets\AceGUIWidget-Icon.lua"/>
<Script file="widgets\AceGUIWidget-BlizOptionsGroup.lua"/> <Script file="widgets\AceGUIWidget-InteractiveLabel.lua"/>
<Script file="widgets\AceGUIWidget-InteractiveLabel.lua"/> <Script file="widgets\AceGUIWidget-Keybinding.lua"/>
<Script file="widgets\AceGUIWidget-Icon.lua"/> <Script file="widgets\AceGUIWidget-Label.lua"/>
</Ui> <Script file="widgets\AceGUIWidget-MultiLineEditBox.lua"/>
<Script file="widgets\AceGUIWidget-Slider.lua"/>
</Ui>
@@ -0,0 +1,143 @@
--[[-----------------------------------------------------------------------------
BlizOptionsGroup Container
Simple container widget for the integration of AceGUI into the Blizzard Interface Options
-------------------------------------------------------------------------------]]
local Type, Version = "BlizOptionsGroup", 26
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
-- Lua APIs
local pairs = pairs
-- WoW APIs
local CreateFrame = CreateFrame
--[[-----------------------------------------------------------------------------
Scripts
-------------------------------------------------------------------------------]]
local function OnShow(frame)
frame.obj:Fire("OnShow")
end
local function OnHide(frame)
frame.obj:Fire("OnHide")
end
--[[-----------------------------------------------------------------------------
Support functions
-------------------------------------------------------------------------------]]
local function okay(frame)
frame.obj:Fire("okay")
end
local function cancel(frame)
frame.obj:Fire("cancel")
end
local function default(frame)
frame.obj:Fire("default")
end
local function refresh(frame)
frame.obj:Fire("refresh")
end
--[[-----------------------------------------------------------------------------
Methods
-------------------------------------------------------------------------------]]
local methods = {
["OnAcquire"] = function(self)
self:SetName()
self:SetTitle()
end,
-- ["OnRelease"] = nil,
["OnWidthSet"] = function(self, width)
local content = self.content
local contentwidth = width - 63
if contentwidth < 0 then
contentwidth = 0
end
content:SetWidth(contentwidth)
content.width = contentwidth
end,
["OnHeightSet"] = function(self, height)
local content = self.content
local contentheight = height - 26
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end,
["SetName"] = function(self, name, parent)
self.frame.name = name
self.frame.parent = parent
end,
["SetTitle"] = function(self, title)
local content = self.content
content:ClearAllPoints()
if not title or title == "" then
content:SetPoint("TOPLEFT", 10, -10)
self.label:SetText("")
else
content:SetPoint("TOPLEFT", 10, -40)
self.label:SetText(title)
end
content:SetPoint("BOTTOMRIGHT", -10, 10)
end
}
--[[-----------------------------------------------------------------------------
Constructor
-------------------------------------------------------------------------------]]
local function Constructor()
local frame = CreateFrame("Frame", nil, InterfaceOptionsFramePanelContainer)
frame:Hide()
-- support functions for the Blizzard Interface Options
frame.okay = okay
frame.cancel = cancel
frame.default = default
frame.refresh = refresh
-- 10.0 support function aliases (cancel has been removed)
frame.OnCommit = okay
frame.OnDefault = default
frame.OnRefresh = refresh
frame:SetScript("OnHide", OnHide)
frame:SetScript("OnShow", OnShow)
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
label:SetPoint("TOPLEFT", 10, -15)
label:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", 10, -45)
label:SetJustifyH("LEFT")
label:SetJustifyV("TOP")
--Container Support
local content = CreateFrame("Frame", nil, frame)
content:SetPoint("TOPLEFT", 10, -10)
content:SetPoint("BOTTOMRIGHT", -10, 10)
local widget = {
label = label,
frame = frame,
content = content,
type = Type
}
for method, func in pairs(methods) do
widget[method] = func
end
return AceGUI:RegisterAsContainer(widget)
end
AceGUI:RegisterWidgetType(Type, Constructor, Version)
@@ -0,0 +1,157 @@
--[[-----------------------------------------------------------------------------
DropdownGroup Container
Container controlled by a dropdown on the top.
-------------------------------------------------------------------------------]]
local Type, Version = "DropdownGroup", 22
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
-- Lua APIs
local assert, pairs, type = assert, pairs, type
-- WoW APIs
local CreateFrame = CreateFrame
--[[-----------------------------------------------------------------------------
Scripts
-------------------------------------------------------------------------------]]
local function SelectedGroup(self, event, value)
local group = self.parentgroup
local status = group.status or group.localstatus
status.selected = value
self.parentgroup:Fire("OnGroupSelected", value)
end
--[[-----------------------------------------------------------------------------
Methods
-------------------------------------------------------------------------------]]
local methods = {
["OnAcquire"] = function(self)
self.dropdown:SetText("")
self:SetDropdownWidth(200)
self:SetTitle("")
end,
["OnRelease"] = function(self)
self.dropdown.list = nil
self.status = nil
for k in pairs(self.localstatus) do
self.localstatus[k] = nil
end
end,
["SetTitle"] = function(self, title)
self.titletext:SetText(title)
self.dropdown.frame:ClearAllPoints()
if title and title ~= "" then
self.dropdown.frame:SetPoint("TOPRIGHT", -2, 0)
else
self.dropdown.frame:SetPoint("TOPLEFT", -1, 0)
end
end,
["SetGroupList"] = function(self,list,order)
self.dropdown:SetList(list,order)
end,
["SetStatusTable"] = function(self, status)
assert(type(status) == "table")
self.status = status
end,
["SetGroup"] = function(self,group)
self.dropdown:SetValue(group)
local status = self.status or self.localstatus
status.selected = group
self:Fire("OnGroupSelected", group)
end,
["OnWidthSet"] = function(self, width)
local content = self.content
local contentwidth = width - 26
if contentwidth < 0 then
contentwidth = 0
end
content:SetWidth(contentwidth)
content.width = contentwidth
end,
["OnHeightSet"] = function(self, height)
local content = self.content
local contentheight = height - 63
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end,
["LayoutFinished"] = function(self, width, height)
self:SetHeight((height or 0) + 63)
end,
["SetDropdownWidth"] = function(self, width)
self.dropdown:SetWidth(width)
end
}
--[[-----------------------------------------------------------------------------
Constructor
-------------------------------------------------------------------------------]]
local PaneBackdrop = {
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 16,
insets = { left = 3, right = 3, top = 5, bottom = 3 }
}
local function Constructor()
local frame = CreateFrame("Frame")
frame:SetHeight(100)
frame:SetWidth(100)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
local titletext = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
titletext:SetPoint("TOPLEFT", 4, -5)
titletext:SetPoint("TOPRIGHT", -4, -5)
titletext:SetJustifyH("LEFT")
titletext:SetHeight(18)
local dropdown = AceGUI:Create("Dropdown")
dropdown.frame:SetParent(frame)
dropdown.frame:SetFrameLevel(dropdown.frame:GetFrameLevel() + 2)
dropdown:SetCallback("OnValueChanged", SelectedGroup)
dropdown.frame:SetPoint("TOPLEFT", -1, 0)
dropdown.frame:Show()
dropdown:SetLabel("")
local border = CreateFrame("Frame", nil, frame, "BackdropTemplate")
border:SetPoint("TOPLEFT", 0, -26)
border:SetPoint("BOTTOMRIGHT", 0, 3)
border:SetBackdrop(PaneBackdrop)
border:SetBackdropColor(0.1,0.1,0.1,0.5)
border:SetBackdropBorderColor(0.4,0.4,0.4)
--Container Support
local content = CreateFrame("Frame", nil, border)
content:SetPoint("TOPLEFT", 10, -10)
content:SetPoint("BOTTOMRIGHT", -10, 10)
local widget = {
frame = frame,
localstatus = {},
titletext = titletext,
dropdown = dropdown,
border = border,
content = content,
type = Type
}
for method, func in pairs(methods) do
widget[method] = func
end
dropdown.parentgroup = widget
return AceGUI:RegisterAsContainer(widget)
end
AceGUI:RegisterWidgetType(Type, Constructor, Version)
@@ -0,0 +1,318 @@
--[[-----------------------------------------------------------------------------
Frame Container
-------------------------------------------------------------------------------]]
local Type, Version = "Frame", 30
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
-- Lua APIs
local pairs, assert, type = pairs, assert, type
local wipe = table.wipe
-- WoW APIs
local PlaySound = PlaySound
local CreateFrame, UIParent = CreateFrame, UIParent
--[[-----------------------------------------------------------------------------
Scripts
-------------------------------------------------------------------------------]]
local function Button_OnClick(frame)
PlaySound(799) -- SOUNDKIT.GS_TITLE_OPTION_EXIT
frame.obj:Hide()
end
local function Frame_OnShow(frame)
frame.obj:Fire("OnShow")
end
local function Frame_OnClose(frame)
frame.obj:Fire("OnClose")
end
local function Frame_OnMouseDown(frame)
AceGUI:ClearFocus()
end
local function Title_OnMouseDown(frame)
frame:GetParent():StartMoving()
AceGUI:ClearFocus()
end
local function MoverSizer_OnMouseUp(mover)
local frame = mover:GetParent()
frame:StopMovingOrSizing()
local self = frame.obj
local status = self.status or self.localstatus
status.width = frame:GetWidth()
status.height = frame:GetHeight()
status.top = frame:GetTop()
status.left = frame:GetLeft()
end
local function SizerSE_OnMouseDown(frame)
frame:GetParent():StartSizing("BOTTOMRIGHT")
AceGUI:ClearFocus()
end
local function SizerS_OnMouseDown(frame)
frame:GetParent():StartSizing("BOTTOM")
AceGUI:ClearFocus()
end
local function SizerE_OnMouseDown(frame)
frame:GetParent():StartSizing("RIGHT")
AceGUI:ClearFocus()
end
local function StatusBar_OnEnter(frame)
frame.obj:Fire("OnEnterStatusBar")
end
local function StatusBar_OnLeave(frame)
frame.obj:Fire("OnLeaveStatusBar")
end
--[[-----------------------------------------------------------------------------
Methods
-------------------------------------------------------------------------------]]
local methods = {
["OnAcquire"] = function(self)
self.frame:SetParent(UIParent)
self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
self.frame:SetFrameLevel(100) -- Lots of room to draw under it
self:SetTitle()
self:SetStatusText()
self:ApplyStatus()
self:Show()
self:EnableResize(true)
end,
["OnRelease"] = function(self)
self.status = nil
wipe(self.localstatus)
end,
["OnWidthSet"] = function(self, width)
local content = self.content
local contentwidth = width - 34
if contentwidth < 0 then
contentwidth = 0
end
content:SetWidth(contentwidth)
content.width = contentwidth
end,
["OnHeightSet"] = function(self, height)
local content = self.content
local contentheight = height - 57
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end,
["SetTitle"] = function(self, title)
self.titletext:SetText(title)
self.titlebg:SetWidth((self.titletext:GetWidth() or 0) + 10)
end,
["SetStatusText"] = function(self, text)
self.statustext:SetText(text)
end,
["Hide"] = function(self)
self.frame:Hide()
end,
["Show"] = function(self)
self.frame:Show()
end,
["EnableResize"] = function(self, state)
local func = state and "Show" or "Hide"
self.sizer_se[func](self.sizer_se)
self.sizer_s[func](self.sizer_s)
self.sizer_e[func](self.sizer_e)
end,
-- called to set an external table to store status in
["SetStatusTable"] = function(self, status)
assert(type(status) == "table")
self.status = status
self:ApplyStatus()
end,
["ApplyStatus"] = function(self)
local status = self.status or self.localstatus
local frame = self.frame
self:SetWidth(status.width or 700)
self:SetHeight(status.height or 500)
frame:ClearAllPoints()
if status.top and status.left then
frame:SetPoint("TOP", UIParent, "BOTTOM", 0, status.top)
frame:SetPoint("LEFT", UIParent, "LEFT", status.left, 0)
else
frame:SetPoint("CENTER")
end
end
}
--[[-----------------------------------------------------------------------------
Constructor
-------------------------------------------------------------------------------]]
local FrameBackdrop = {
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
tile = true, tileSize = 32, edgeSize = 32,
insets = { left = 8, right = 8, top = 8, bottom = 8 }
}
local PaneBackdrop = {
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 16,
insets = { left = 3, right = 3, top = 5, bottom = 3 }
}
local function Constructor()
local frame = CreateFrame("Frame", nil, UIParent, "BackdropTemplate")
frame:Hide()
frame:EnableMouse(true)
frame:SetMovable(true)
frame:SetResizable(true)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
frame:SetFrameLevel(100) -- Lots of room to draw under it
frame:SetBackdrop(FrameBackdrop)
frame:SetBackdropColor(0, 0, 0, 1)
if frame.SetResizeBounds then -- WoW 10.0
frame:SetResizeBounds(400, 200)
else
frame:SetMinResize(400, 200)
end
frame:SetToplevel(true)
frame:SetScript("OnShow", Frame_OnShow)
frame:SetScript("OnHide", Frame_OnClose)
frame:SetScript("OnMouseDown", Frame_OnMouseDown)
local closebutton = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
closebutton:SetScript("OnClick", Button_OnClick)
closebutton:SetPoint("BOTTOMRIGHT", -27, 17)
closebutton:SetHeight(20)
closebutton:SetWidth(100)
closebutton:SetText(CLOSE)
local statusbg = CreateFrame("Button", nil, frame, "BackdropTemplate")
statusbg:SetPoint("BOTTOMLEFT", 15, 15)
statusbg:SetPoint("BOTTOMRIGHT", -132, 15)
statusbg:SetHeight(24)
statusbg:SetBackdrop(PaneBackdrop)
statusbg:SetBackdropColor(0.1,0.1,0.1)
statusbg:SetBackdropBorderColor(0.4,0.4,0.4)
statusbg:SetScript("OnEnter", StatusBar_OnEnter)
statusbg:SetScript("OnLeave", StatusBar_OnLeave)
local statustext = statusbg:CreateFontString(nil, "OVERLAY", "GameFontNormal")
statustext:SetPoint("TOPLEFT", 7, -2)
statustext:SetPoint("BOTTOMRIGHT", -7, 2)
statustext:SetHeight(20)
statustext:SetJustifyH("LEFT")
statustext:SetText("")
local titlebg = frame:CreateTexture(nil, "OVERLAY")
titlebg:SetTexture(131080) -- Interface\\DialogFrame\\UI-DialogBox-Header
titlebg:SetTexCoord(0.31, 0.67, 0, 0.63)
titlebg:SetPoint("TOP", 0, 12)
titlebg:SetWidth(100)
titlebg:SetHeight(40)
local title = CreateFrame("Frame", nil, frame)
title:EnableMouse(true)
title:SetScript("OnMouseDown", Title_OnMouseDown)
title:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
title:SetAllPoints(titlebg)
local titletext = title:CreateFontString(nil, "OVERLAY", "GameFontNormal")
titletext:SetPoint("TOP", titlebg, "TOP", 0, -14)
local titlebg_l = frame:CreateTexture(nil, "OVERLAY")
titlebg_l:SetTexture(131080) -- Interface\\DialogFrame\\UI-DialogBox-Header
titlebg_l:SetTexCoord(0.21, 0.31, 0, 0.63)
titlebg_l:SetPoint("RIGHT", titlebg, "LEFT")
titlebg_l:SetWidth(30)
titlebg_l:SetHeight(40)
local titlebg_r = frame:CreateTexture(nil, "OVERLAY")
titlebg_r:SetTexture(131080) -- Interface\\DialogFrame\\UI-DialogBox-Header
titlebg_r:SetTexCoord(0.67, 0.77, 0, 0.63)
titlebg_r:SetPoint("LEFT", titlebg, "RIGHT")
titlebg_r:SetWidth(30)
titlebg_r:SetHeight(40)
local sizer_se = CreateFrame("Frame", nil, frame)
sizer_se:SetPoint("BOTTOMRIGHT")
sizer_se:SetWidth(25)
sizer_se:SetHeight(25)
sizer_se:EnableMouse()
sizer_se:SetScript("OnMouseDown",SizerSE_OnMouseDown)
sizer_se:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
local line1 = sizer_se:CreateTexture(nil, "BACKGROUND")
line1:SetWidth(14)
line1:SetHeight(14)
line1:SetPoint("BOTTOMRIGHT", -8, 8)
line1:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border
local x = 0.1 * 14/17
line1:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
local line2 = sizer_se:CreateTexture(nil, "BACKGROUND")
line2:SetWidth(8)
line2:SetHeight(8)
line2:SetPoint("BOTTOMRIGHT", -8, 8)
line2:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border
x = 0.1 * 8/17
line2:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
local sizer_s = CreateFrame("Frame", nil, frame)
sizer_s:SetPoint("BOTTOMRIGHT", -25, 0)
sizer_s:SetPoint("BOTTOMLEFT")
sizer_s:SetHeight(25)
sizer_s:EnableMouse(true)
sizer_s:SetScript("OnMouseDown", SizerS_OnMouseDown)
sizer_s:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
local sizer_e = CreateFrame("Frame", nil, frame)
sizer_e:SetPoint("BOTTOMRIGHT", 0, 25)
sizer_e:SetPoint("TOPRIGHT")
sizer_e:SetWidth(25)
sizer_e:EnableMouse(true)
sizer_e:SetScript("OnMouseDown", SizerE_OnMouseDown)
sizer_e:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
--Container Support
local content = CreateFrame("Frame", nil, frame)
content:SetPoint("TOPLEFT", 17, -27)
content:SetPoint("BOTTOMRIGHT", -17, 40)
local widget = {
localstatus = {},
titletext = titletext,
statustext = statustext,
titlebg = titlebg,
sizer_se = sizer_se,
sizer_s = sizer_s,
sizer_e = sizer_e,
content = content,
frame = frame,
type = Type
}
for method, func in pairs(methods) do
widget[method] = func
end
closebutton.obj, statusbg.obj = widget, widget
return AceGUI:RegisterAsContainer(widget)
end
AceGUI:RegisterWidgetType(Type, Constructor, Version)
@@ -0,0 +1,103 @@
--[[-----------------------------------------------------------------------------
InlineGroup Container
Simple container widget that creates a visible "box" with an optional title.
-------------------------------------------------------------------------------]]
local Type, Version = "InlineGroup", 22
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
-- Lua APIs
local pairs = pairs
-- WoW APIs
local CreateFrame, UIParent = CreateFrame, UIParent
--[[-----------------------------------------------------------------------------
Methods
-------------------------------------------------------------------------------]]
local methods = {
["OnAcquire"] = function(self)
self:SetWidth(300)
self:SetHeight(100)
self:SetTitle("")
end,
-- ["OnRelease"] = nil,
["SetTitle"] = function(self,title)
self.titletext:SetText(title)
end,
["LayoutFinished"] = function(self, width, height)
if self.noAutoHeight then return end
self:SetHeight((height or 0) + 40)
end,
["OnWidthSet"] = function(self, width)
local content = self.content
local contentwidth = width - 20
if contentwidth < 0 then
contentwidth = 0
end
content:SetWidth(contentwidth)
content.width = contentwidth
end,
["OnHeightSet"] = function(self, height)
local content = self.content
local contentheight = height - 20
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end
}
--[[-----------------------------------------------------------------------------
Constructor
-------------------------------------------------------------------------------]]
local PaneBackdrop = {
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 16,
insets = { left = 3, right = 3, top = 5, bottom = 3 }
}
local function Constructor()
local frame = CreateFrame("Frame", nil, UIParent)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
local titletext = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
titletext:SetPoint("TOPLEFT", 14, 0)
titletext:SetPoint("TOPRIGHT", -14, 0)
titletext:SetJustifyH("LEFT")
titletext:SetHeight(18)
local border = CreateFrame("Frame", nil, frame, "BackdropTemplate")
border:SetPoint("TOPLEFT", 0, -17)
border:SetPoint("BOTTOMRIGHT", -1, 3)
border:SetBackdrop(PaneBackdrop)
border:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
border:SetBackdropBorderColor(0.4, 0.4, 0.4)
--Container Support
local content = CreateFrame("Frame", nil, border)
content:SetPoint("TOPLEFT", 10, -10)
content:SetPoint("BOTTOMRIGHT", -10, 10)
local widget = {
frame = frame,
content = content,
titletext = titletext,
type = Type
}
for method, func in pairs(methods) do
widget[method] = func
end
return AceGUI:RegisterAsContainer(widget)
end
AceGUI:RegisterWidgetType(Type, Constructor, Version)
@@ -0,0 +1,215 @@
--[[-----------------------------------------------------------------------------
ScrollFrame Container
Plain container that scrolls its content and doesn't grow in height.
-------------------------------------------------------------------------------]]
local Type, Version = "ScrollFrame", 26
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
-- Lua APIs
local pairs, assert, type = pairs, assert, type
local min, max, floor = math.min, math.max, math.floor
-- WoW APIs
local CreateFrame, UIParent = CreateFrame, UIParent
--[[-----------------------------------------------------------------------------
Support functions
-------------------------------------------------------------------------------]]
local function FixScrollOnUpdate(frame)
frame:SetScript("OnUpdate", nil)
frame.obj:FixScroll()
end
--[[-----------------------------------------------------------------------------
Scripts
-------------------------------------------------------------------------------]]
local function ScrollFrame_OnMouseWheel(frame, value)
frame.obj:MoveScroll(value)
end
local function ScrollFrame_OnSizeChanged(frame)
frame:SetScript("OnUpdate", FixScrollOnUpdate)
end
local function ScrollBar_OnScrollValueChanged(frame, value)
frame.obj:SetScroll(value)
end
--[[-----------------------------------------------------------------------------
Methods
-------------------------------------------------------------------------------]]
local methods = {
["OnAcquire"] = function(self)
self:SetScroll(0)
self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate)
end,
["OnRelease"] = function(self)
self.status = nil
for k in pairs(self.localstatus) do
self.localstatus[k] = nil
end
self.scrollframe:SetPoint("BOTTOMRIGHT")
self.scrollbar:Hide()
self.scrollBarShown = nil
self.content.height, self.content.width, self.content.original_width = nil, nil, nil
end,
["SetScroll"] = function(self, value)
local status = self.status or self.localstatus
local viewheight = self.scrollframe:GetHeight()
local height = self.content:GetHeight()
local offset
if viewheight > height then
offset = 0
else
offset = floor((height - viewheight) / 1000.0 * value)
end
self.content:ClearAllPoints()
self.content:SetPoint("TOPLEFT", 0, offset)
self.content:SetPoint("TOPRIGHT", 0, offset)
status.offset = offset
status.scrollvalue = value
end,
["MoveScroll"] = function(self, value)
local status = self.status or self.localstatus
local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
if self.scrollBarShown then
local diff = height - viewheight
local delta = 1
if value < 0 then
delta = -1
end
self.scrollbar:SetValue(min(max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000))
end
end,
["FixScroll"] = function(self)
if self.updateLock then return end
self.updateLock = true
local status = self.status or self.localstatus
local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
local offset = status.offset or 0
-- Give us a margin of error of 2 pixels to stop some conditions that i would blame on floating point inaccuracys
-- No-one is going to miss 2 pixels at the bottom of the frame, anyhow!
if viewheight < height + 2 then
if self.scrollBarShown then
self.scrollBarShown = nil
self.scrollbar:Hide()
self.scrollbar:SetValue(0)
self.scrollframe:SetPoint("BOTTOMRIGHT")
if self.content.original_width then
self.content.width = self.content.original_width
end
self:DoLayout()
end
else
if not self.scrollBarShown then
self.scrollBarShown = true
self.scrollbar:Show()
self.scrollframe:SetPoint("BOTTOMRIGHT", -20, 0)
if self.content.original_width then
self.content.width = self.content.original_width - 20
end
self:DoLayout()
end
local value = (offset / (viewheight - height) * 1000)
if value > 1000 then value = 1000 end
self.scrollbar:SetValue(value)
self:SetScroll(value)
if value < 1000 then
self.content:ClearAllPoints()
self.content:SetPoint("TOPLEFT", 0, offset)
self.content:SetPoint("TOPRIGHT", 0, offset)
status.offset = offset
end
end
self.updateLock = nil
end,
["LayoutFinished"] = function(self, width, height)
self.content:SetHeight(height or 0 + 20)
-- update the scrollframe
self:FixScroll()
-- schedule another update when everything has "settled"
self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate)
end,
["SetStatusTable"] = function(self, status)
assert(type(status) == "table")
self.status = status
if not status.scrollvalue then
status.scrollvalue = 0
end
end,
["OnWidthSet"] = function(self, width)
local content = self.content
content.width = width - (self.scrollBarShown and 20 or 0)
content.original_width = width
end,
["OnHeightSet"] = function(self, height)
local content = self.content
content.height = height
end
}
--[[-----------------------------------------------------------------------------
Constructor
-------------------------------------------------------------------------------]]
local function Constructor()
local frame = CreateFrame("Frame", nil, UIParent)
local num = AceGUI:GetNextWidgetNum(Type)
local scrollframe = CreateFrame("ScrollFrame", nil, frame)
scrollframe:SetPoint("TOPLEFT")
scrollframe:SetPoint("BOTTOMRIGHT")
scrollframe:EnableMouseWheel(true)
scrollframe:SetScript("OnMouseWheel", ScrollFrame_OnMouseWheel)
scrollframe:SetScript("OnSizeChanged", ScrollFrame_OnSizeChanged)
local scrollbar = CreateFrame("Slider", ("AceConfigDialogScrollFrame%dScrollBar"):format(num), scrollframe, "UIPanelScrollBarTemplate")
scrollbar:SetPoint("TOPLEFT", scrollframe, "TOPRIGHT", 4, -16)
scrollbar:SetPoint("BOTTOMLEFT", scrollframe, "BOTTOMRIGHT", 4, 16)
scrollbar:SetMinMaxValues(0, 1000)
scrollbar:SetValueStep(1)
scrollbar:SetValue(0)
scrollbar:SetWidth(16)
scrollbar:Hide()
-- set the script as the last step, so it doesn't fire yet
scrollbar:SetScript("OnValueChanged", ScrollBar_OnScrollValueChanged)
local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND")
scrollbg:SetAllPoints(scrollbar)
scrollbg:SetColorTexture(0, 0, 0, 0.4)
--Container Support
local content = CreateFrame("Frame", nil, scrollframe)
content:SetPoint("TOPLEFT")
content:SetPoint("TOPRIGHT")
content:SetHeight(400)
scrollframe:SetScrollChild(content)
local widget = {
localstatus = { scrollvalue = 0 },
scrollframe = scrollframe,
scrollbar = scrollbar,
content = content,
frame = frame,
type = Type
}
for method, func in pairs(methods) do
widget[method] = func
end
scrollframe.obj, scrollbar.obj = widget, widget
return AceGUI:RegisterAsContainer(widget)
end
AceGUI:RegisterWidgetType(Type, Constructor, Version)
@@ -0,0 +1,69 @@
--[[-----------------------------------------------------------------------------
SimpleGroup Container
Simple container widget that just groups widgets.
-------------------------------------------------------------------------------]]
local Type, Version = "SimpleGroup", 20
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
-- Lua APIs
local pairs = pairs
-- WoW APIs
local CreateFrame, UIParent = CreateFrame, UIParent
--[[-----------------------------------------------------------------------------
Methods
-------------------------------------------------------------------------------]]
local methods = {
["OnAcquire"] = function(self)
self:SetWidth(300)
self:SetHeight(100)
end,
-- ["OnRelease"] = nil,
["LayoutFinished"] = function(self, width, height)
if self.noAutoHeight then return end
self:SetHeight(height or 0)
end,
["OnWidthSet"] = function(self, width)
local content = self.content
content:SetWidth(width)
content.width = width
end,
["OnHeightSet"] = function(self, height)
local content = self.content
content:SetHeight(height)
content.height = height
end
}
--[[-----------------------------------------------------------------------------
Constructor
-------------------------------------------------------------------------------]]
local function Constructor()
local frame = CreateFrame("Frame", nil, UIParent)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
--Container Support
local content = CreateFrame("Frame", nil, frame)
content:SetPoint("TOPLEFT")
content:SetPoint("BOTTOMRIGHT")
local widget = {
frame = frame,
content = content,
type = Type
}
for method, func in pairs(methods) do
widget[method] = func
end
return AceGUI:RegisterAsContainer(widget)
end
AceGUI:RegisterWidgetType(Type, Constructor, Version)
@@ -0,0 +1,535 @@
--[[-----------------------------------------------------------------------------
TabGroup Container
Container that uses tabs on top to switch between groups.
-------------------------------------------------------------------------------]]
local Type, Version = "TabGroup", 38
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
-- Lua APIs
local pairs, ipairs, assert, type, wipe = pairs, ipairs, assert, type, table.wipe
-- WoW APIs
local PlaySound = PlaySound
local CreateFrame, UIParent = CreateFrame, UIParent
local _G = _G
-- local upvalue storage used by BuildTabs
local widths = {}
local rowwidths = {}
local rowends = {}
--[[-----------------------------------------------------------------------------
Support functions
-------------------------------------------------------------------------------]]
local function PanelTemplates_TabResize(tab, padding, absoluteSize, minWidth, maxWidth, absoluteTextSize)
local tabName = tab:GetName();
local buttonMiddle = tab.Middle or tab.middleTexture or _G[tabName.."Middle"];
local buttonMiddleDisabled = tab.MiddleDisabled or (tabName and _G[tabName.."MiddleDisabled"]);
local left = tab.Left or tab.leftTexture or _G[tabName.."Left"];
local sideWidths = 2 * left:GetWidth();
local tabText = tab.Text or _G[tab:GetName().."Text"];
local highlightTexture = tab.HighlightTexture or (tabName and _G[tabName.."HighlightTexture"]);
local width, tabWidth;
local textWidth;
if ( absoluteTextSize ) then
textWidth = absoluteTextSize;
else
tabText:SetWidth(0);
textWidth = tabText:GetWidth();
end
-- If there's an absolute size specified then use it
if ( absoluteSize ) then
if ( absoluteSize < sideWidths) then
width = 1;
tabWidth = sideWidths
else
width = absoluteSize - sideWidths;
tabWidth = absoluteSize
end
tabText:SetWidth(width);
else
-- Otherwise try to use padding
if ( padding ) then
width = textWidth + padding;
else
width = textWidth + 24;
end
-- If greater than the maxWidth then cap it
if ( maxWidth and width > maxWidth ) then
if ( padding ) then
width = maxWidth + padding;
else
width = maxWidth + 24;
end
tabText:SetWidth(width);
else
tabText:SetWidth(0);
end
if (minWidth and width < minWidth) then
width = minWidth;
end
tabWidth = width + sideWidths;
end
if ( buttonMiddle ) then
buttonMiddle:SetWidth(width);
end
if ( buttonMiddleDisabled ) then
buttonMiddleDisabled:SetWidth(width);
end
tab:SetWidth(tabWidth);
if ( highlightTexture ) then
highlightTexture:SetWidth(tabWidth);
end
end
local function PanelTemplates_DeselectTab(tab)
local name = tab:GetName();
local left = tab.Left or _G[name.."Left"];
local middle = tab.Middle or _G[name.."Middle"];
local right = tab.Right or _G[name.."Right"];
left:Show();
middle:Show();
right:Show();
--tab:UnlockHighlight();
tab:Enable();
local text = tab.Text or _G[name.."Text"];
text:SetPoint("CENTER", tab, "CENTER", (tab.deselectedTextX or 0), (tab.deselectedTextY or 2));
local leftDisabled = tab.LeftDisabled or _G[name.."LeftDisabled"];
local middleDisabled = tab.MiddleDisabled or _G[name.."MiddleDisabled"];
local rightDisabled = tab.RightDisabled or _G[name.."RightDisabled"];
leftDisabled:Hide();
middleDisabled:Hide();
rightDisabled:Hide();
end
local function PanelTemplates_SelectTab(tab)
local name = tab:GetName();
local left = tab.Left or _G[name.."Left"];
local middle = tab.Middle or _G[name.."Middle"];
local right = tab.Right or _G[name.."Right"];
left:Hide();
middle:Hide();
right:Hide();
--tab:LockHighlight();
tab:Disable();
tab:SetDisabledFontObject(GameFontHighlightSmall);
local text = tab.Text or _G[name.."Text"];
text:SetPoint("CENTER", tab, "CENTER", (tab.selectedTextX or 0), (tab.selectedTextY or -3));
local leftDisabled = tab.LeftDisabled or _G[name.."LeftDisabled"];
local middleDisabled = tab.MiddleDisabled or _G[name.."MiddleDisabled"];
local rightDisabled = tab.RightDisabled or _G[name.."RightDisabled"];
leftDisabled:Show();
middleDisabled:Show();
rightDisabled:Show();
if GameTooltip:IsOwned(tab) then
GameTooltip:Hide();
end
end
local function PanelTemplates_SetDisabledTabState(tab)
local name = tab:GetName();
local left = tab.Left or _G[name.."Left"];
local middle = tab.Middle or _G[name.."Middle"];
local right = tab.Right or _G[name.."Right"];
left:Show();
middle:Show();
right:Show();
--tab:UnlockHighlight();
tab:Disable();
tab.text = tab:GetText();
-- Gray out text
tab:SetDisabledFontObject(GameFontDisableSmall);
local leftDisabled = tab.LeftDisabled or _G[name.."LeftDisabled"];
local middleDisabled = tab.MiddleDisabled or _G[name.."MiddleDisabled"];
local rightDisabled = tab.RightDisabled or _G[name.."RightDisabled"];
leftDisabled:Hide();
middleDisabled:Hide();
rightDisabled:Hide();
end
local function UpdateTabLook(frame)
if frame.disabled then
PanelTemplates_SetDisabledTabState(frame)
elseif frame.selected then
PanelTemplates_SelectTab(frame)
else
PanelTemplates_DeselectTab(frame)
end
end
local function Tab_SetText(frame, text)
frame:_SetText(text)
local width = frame.obj.frame.width or frame.obj.frame:GetWidth() or 0
PanelTemplates_TabResize(frame, 0, nil, nil, width, frame:GetFontString():GetStringWidth())
end
local function Tab_SetSelected(frame, selected)
frame.selected = selected
UpdateTabLook(frame)
end
local function Tab_SetDisabled(frame, disabled)
frame.disabled = disabled
UpdateTabLook(frame)
end
local function BuildTabsOnUpdate(frame)
local self = frame.obj
self:BuildTabs()
frame:SetScript("OnUpdate", nil)
end
--[[-----------------------------------------------------------------------------
Scripts
-------------------------------------------------------------------------------]]
local function Tab_OnClick(frame)
if not (frame.selected or frame.disabled) then
PlaySound(841) -- SOUNDKIT.IG_CHARACTER_INFO_TAB
frame.obj:SelectTab(frame.value)
end
end
local function Tab_OnEnter(frame)
local self = frame.obj
self:Fire("OnTabEnter", self.tabs[frame.id].value, frame)
end
local function Tab_OnLeave(frame)
local self = frame.obj
self:Fire("OnTabLeave", self.tabs[frame.id].value, frame)
end
local function Tab_OnShow(frame)
_G[frame:GetName().."HighlightTexture"]:SetWidth(frame:GetTextWidth() + 30)
end
--[[-----------------------------------------------------------------------------
Methods
-------------------------------------------------------------------------------]]
local methods = {
["OnAcquire"] = function(self)
self:SetTitle()
end,
["OnRelease"] = function(self)
self.status = nil
for k in pairs(self.localstatus) do
self.localstatus[k] = nil
end
self.tablist = nil
for _, tab in pairs(self.tabs) do
tab:Hide()
end
end,
["CreateTab"] = function(self, id)
local tabname = ("AceGUITabGroup%dTab%d"):format(self.num, id)
local tab = CreateFrame("Button", tabname, self.border)
tab:SetSize(115, 24)
tab.deselectedTextY = -3
tab.selectedTextY = -2
tab.LeftDisabled = tab:CreateTexture(tabname .. "LeftDisabled", "BORDER")
tab.LeftDisabled:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-ActiveTab")
tab.LeftDisabled:SetSize(20, 24)
tab.LeftDisabled:SetPoint("BOTTOMLEFT", 0, -3)
tab.LeftDisabled:SetTexCoord(0, 0.15625, 0, 1.0)
tab.MiddleDisabled = tab:CreateTexture(tabname .. "MiddleDisabled", "BORDER")
tab.MiddleDisabled:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-ActiveTab")
tab.MiddleDisabled:SetSize(88, 24)
tab.MiddleDisabled:SetPoint("LEFT", tab.LeftDisabled, "RIGHT")
tab.MiddleDisabled:SetTexCoord(0.15625, 0.84375, 0, 1.0)
tab.RightDisabled = tab:CreateTexture(tabname .. "RightDisabled", "BORDER")
tab.RightDisabled:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-ActiveTab")
tab.RightDisabled:SetSize(20, 24)
tab.RightDisabled:SetPoint("LEFT", tab.MiddleDisabled, "RIGHT")
tab.RightDisabled:SetTexCoord(0.84375, 1.0, 0, 1.0)
tab.Left = tab:CreateTexture(tabname .. "Left", "BORDER")
tab.Left:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-InActiveTab")
tab.Left:SetSize(20, 24)
tab.Left:SetPoint("TOPLEFT")
tab.Left:SetTexCoord(0, 0.15625, 0, 1.0)
tab.Middle = tab:CreateTexture(tabname .. "Middle", "BORDER")
tab.Middle:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-InActiveTab")
tab.Middle:SetSize(88, 24)
tab.Middle:SetPoint("LEFT", tab.Left, "RIGHT")
tab.Middle:SetTexCoord(0.15625, 0.84375, 0, 1.0)
tab.Right = tab:CreateTexture(tabname .. "Right", "BORDER")
tab.Right:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-InActiveTab")
tab.Right:SetSize(20, 24)
tab.Right:SetPoint("LEFT", tab.Middle, "RIGHT")
tab.Right:SetTexCoord(0.84375, 1.0, 0, 1.0)
tab.Text = tab:CreateFontString(tabname .. "Text")
tab:SetFontString(tab.Text)
tab:SetNormalFontObject(GameFontNormalSmall)
tab:SetHighlightFontObject(GameFontHighlightSmall)
tab:SetDisabledFontObject(GameFontHighlightSmall)
tab:SetHighlightTexture("Interface\\PaperDollInfoFrame\\UI-Character-Tab-Highlight", "ADD")
tab.HighlightTexture = tab:GetHighlightTexture()
tab.HighlightTexture:ClearAllPoints()
tab.HighlightTexture:SetPoint("LEFT", tab, "LEFT", 10, -4)
tab.HighlightTexture:SetPoint("RIGHT", tab, "RIGHT", -10, -4)
_G[tabname .. "HighlightTexture"] = tab.HighlightTexture
tab.obj = self
tab.id = id
tab.text = tab.Text -- compat
tab.text:ClearAllPoints()
tab.text:SetPoint("LEFT", 14, -3)
tab.text:SetPoint("RIGHT", -12, -3)
tab:SetScript("OnClick", Tab_OnClick)
tab:SetScript("OnEnter", Tab_OnEnter)
tab:SetScript("OnLeave", Tab_OnLeave)
tab:SetScript("OnShow", Tab_OnShow)
tab._SetText = tab.SetText
tab.SetText = Tab_SetText
tab.SetSelected = Tab_SetSelected
tab.SetDisabled = Tab_SetDisabled
return tab
end,
["SetTitle"] = function(self, text)
self.titletext:SetText(text or "")
if text and text ~= "" then
self.alignoffset = 25
else
self.alignoffset = 18
end
self:BuildTabs()
end,
["SetStatusTable"] = function(self, status)
assert(type(status) == "table")
self.status = status
end,
["SelectTab"] = function(self, value)
local status = self.status or self.localstatus
local found
for i, v in ipairs(self.tabs) do
if v.value == value then
v:SetSelected(true)
found = true
else
v:SetSelected(false)
end
end
status.selected = value
if found then
self:Fire("OnGroupSelected",value)
end
end,
["SetTabs"] = function(self, tabs)
self.tablist = tabs
self:BuildTabs()
end,
["BuildTabs"] = function(self)
local hastitle = (self.titletext:GetText() and self.titletext:GetText() ~= "")
local tablist = self.tablist
local tabs = self.tabs
if not tablist then return end
local width = self.frame.width or self.frame:GetWidth() or 0
wipe(widths)
wipe(rowwidths)
wipe(rowends)
--Place Text into tabs and get thier initial width
for i, v in ipairs(tablist) do
local tab = tabs[i]
if not tab then
tab = self:CreateTab(i)
tabs[i] = tab
end
tab:Show()
tab:SetText(v.text)
tab:SetDisabled(v.disabled)
tab.value = v.value
widths[i] = tab:GetWidth() - 6 --tabs are anchored 10 pixels from the right side of the previous one to reduce spacing, but add a fixed 4px padding for the text
end
for i = (#tablist)+1, #tabs, 1 do
tabs[i]:Hide()
end
--First pass, find the minimum number of rows needed to hold all tabs and the initial tab layout
local numtabs = #tablist
local numrows = 1
local usedwidth = 0
for i = 1, #tablist do
--If this is not the first tab of a row and there isn't room for it
if usedwidth ~= 0 and (width - usedwidth - widths[i]) < 0 then
rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
rowends[numrows] = i - 1
numrows = numrows + 1
usedwidth = 0
end
usedwidth = usedwidth + widths[i]
end
rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
rowends[numrows] = #tablist
--Fix for single tabs being left on the last row, move a tab from the row above if applicable
if numrows > 1 then
--if the last row has only one tab
if rowends[numrows-1] == numtabs-1 then
--if there are more than 2 tabs in the 2nd last row
if (numrows == 2 and rowends[numrows-1] > 2) or (rowends[numrows] - rowends[numrows-1] > 2) then
--move 1 tab from the second last row to the last, if there is enough space
if (rowwidths[numrows] + widths[numtabs-1]) <= width then
rowends[numrows-1] = rowends[numrows-1] - 1
rowwidths[numrows] = rowwidths[numrows] + widths[numtabs-1]
rowwidths[numrows-1] = rowwidths[numrows-1] - widths[numtabs-1]
end
end
end
end
--anchor the rows as defined and resize tabs to fill thier row
local starttab = 1
for row, endtab in ipairs(rowends) do
local first = true
for tabno = starttab, endtab do
local tab = tabs[tabno]
tab:ClearAllPoints()
if first then
tab:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 0, -(hastitle and 14 or 7)-(row-1)*20 )
first = false
else
tab:SetPoint("LEFT", tabs[tabno-1], "RIGHT", -10, 0)
end
end
-- equal padding for each tab to fill the available width,
-- if the used space is above 75% already
-- the 18 pixel is the typical width of a scrollbar, so we can have a tab group inside a scrolling frame,
-- and not have the tabs jump around funny when switching between tabs that need scrolling and those that don't
local padding = 0
if not (numrows == 1 and rowwidths[1] < width*0.75 - 18) then
padding = (width - rowwidths[row]) / (endtab - starttab+1)
end
for i = starttab, endtab do
PanelTemplates_TabResize(tabs[i], padding + 4, nil, nil, width, tabs[i]:GetFontString():GetStringWidth())
end
starttab = endtab + 1
end
self.borderoffset = (hastitle and 17 or 10)+((numrows)*20)
self.border:SetPoint("TOPLEFT", 1, -self.borderoffset)
end,
["OnWidthSet"] = function(self, width)
local content = self.content
local contentwidth = width - 60
if contentwidth < 0 then
contentwidth = 0
end
content:SetWidth(contentwidth)
content.width = contentwidth
self:BuildTabs(self)
self.frame:SetScript("OnUpdate", BuildTabsOnUpdate)
end,
["OnHeightSet"] = function(self, height)
local content = self.content
local contentheight = height - (self.borderoffset + 23)
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end,
["LayoutFinished"] = function(self, width, height)
if self.noAutoHeight then return end
self:SetHeight((height or 0) + (self.borderoffset + 23))
end
}
--[[-----------------------------------------------------------------------------
Constructor
-------------------------------------------------------------------------------]]
local PaneBackdrop = {
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 16,
insets = { left = 3, right = 3, top = 5, bottom = 3 }
}
local function Constructor()
local num = AceGUI:GetNextWidgetNum(Type)
local frame = CreateFrame("Frame",nil,UIParent)
frame:SetHeight(100)
frame:SetWidth(100)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
local titletext = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
titletext:SetPoint("TOPLEFT", 14, 0)
titletext:SetPoint("TOPRIGHT", -14, 0)
titletext:SetJustifyH("LEFT")
titletext:SetHeight(18)
titletext:SetText("")
local border = CreateFrame("Frame", nil, frame, "BackdropTemplate")
border:SetPoint("TOPLEFT", 1, -27)
border:SetPoint("BOTTOMRIGHT", -1, 3)
border:SetBackdrop(PaneBackdrop)
border:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
border:SetBackdropBorderColor(0.4, 0.4, 0.4)
local content = CreateFrame("Frame", nil, border)
content:SetPoint("TOPLEFT", 10, -7)
content:SetPoint("BOTTOMRIGHT", -10, 7)
local widget = {
num = num,
frame = frame,
localstatus = {},
alignoffset = 18,
titletext = titletext,
border = border,
borderoffset = 27,
tabs = {},
content = content,
type = Type
}
for method, func in pairs(methods) do
widget[method] = func
end
return AceGUI:RegisterAsContainer(widget)
end
AceGUI:RegisterWidgetType(Type, Constructor, Version)
@@ -0,0 +1,719 @@
--[[-----------------------------------------------------------------------------
TreeGroup Container
Container that uses a tree control to switch between groups.
-------------------------------------------------------------------------------]]
local Type, Version = "TreeGroup", 49
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
-- Lua APIs
local next, pairs, ipairs, assert, type = next, pairs, ipairs, assert, type
local math_min, math_max, floor = math.min, math.max, math.floor
local select, tremove, unpack, tconcat = select, table.remove, unpack, table.concat
-- WoW APIs
local CreateFrame, UIParent = CreateFrame, UIParent
-- Recycling functions
local new, del
do
local pool = setmetatable({},{__mode='k'})
function new()
local t = next(pool)
if t then
pool[t] = nil
return t
else
return {}
end
end
function del(t)
for k in pairs(t) do
t[k] = nil
end
pool[t] = true
end
end
local DEFAULT_TREE_WIDTH = 175
local DEFAULT_TREE_SIZABLE = true
--[[-----------------------------------------------------------------------------
Support functions
-------------------------------------------------------------------------------]]
local function GetButtonUniqueValue(line)
local parent = line.parent
if parent and parent.value then
return GetButtonUniqueValue(parent).."\001"..line.value
else
return line.value
end
end
local function UpdateButton(button, treeline, selected, canExpand, isExpanded)
local self = button.obj
local toggle = button.toggle
local text = treeline.text or ""
local icon = treeline.icon
local iconCoords = treeline.iconCoords
local level = treeline.level
local value = treeline.value
local uniquevalue = treeline.uniquevalue
local disabled = treeline.disabled
button.treeline = treeline
button.value = value
button.uniquevalue = uniquevalue
if selected then
button:LockHighlight()
button.selected = true
else
button:UnlockHighlight()
button.selected = false
end
button.level = level
if ( level == 1 ) then
button:SetNormalFontObject("GameFontNormal")
button:SetHighlightFontObject("GameFontHighlight")
button.text:SetPoint("LEFT", (icon and 16 or 0) + 8, 2)
else
button:SetNormalFontObject("GameFontHighlightSmall")
button:SetHighlightFontObject("GameFontHighlightSmall")
button.text:SetPoint("LEFT", (icon and 16 or 0) + 8 * level, 2)
end
if disabled then
button:EnableMouse(false)
button.text:SetText("|cff808080"..text..FONT_COLOR_CODE_CLOSE)
else
button.text:SetText(text)
button:EnableMouse(true)
end
if icon then
button.icon:SetTexture(icon)
button.icon:SetPoint("LEFT", 8 * level, (level == 1) and 0 or 1)
else
button.icon:SetTexture(nil)
end
if iconCoords then
button.icon:SetTexCoord(unpack(iconCoords))
else
button.icon:SetTexCoord(0, 1, 0, 1)
end
if canExpand then
if not isExpanded then
toggle:SetNormalTexture(130838) -- Interface\\Buttons\\UI-PlusButton-UP
toggle:SetPushedTexture(130836) -- Interface\\Buttons\\UI-PlusButton-DOWN
else
toggle:SetNormalTexture(130821) -- Interface\\Buttons\\UI-MinusButton-UP
toggle:SetPushedTexture(130820) -- Interface\\Buttons\\UI-MinusButton-DOWN
end
toggle:Show()
else
toggle:Hide()
end
end
local function ShouldDisplayLevel(tree)
local result = false
for k, v in ipairs(tree) do
if v.children == nil and v.visible ~= false then
result = true
elseif v.children then
result = result or ShouldDisplayLevel(v.children)
end
if result then return result end
end
return false
end
local function addLine(self, v, tree, level, parent)
local line = new()
line.value = v.value
line.text = v.text
line.icon = v.icon
line.iconCoords = v.iconCoords
line.disabled = v.disabled
line.tree = tree
line.level = level
line.parent = parent
line.visible = v.visible
line.uniquevalue = GetButtonUniqueValue(line)
if v.children then
line.hasChildren = true
else
line.hasChildren = nil
end
self.lines[#self.lines+1] = line
return line
end
--fire an update after one frame to catch the treeframes height
local function FirstFrameUpdate(frame)
local self = frame.obj
frame:SetScript("OnUpdate", nil)
self:RefreshTree(nil, true)
end
local function BuildUniqueValue(...)
local n = select('#', ...)
if n == 1 then
return ...
else
return (...).."\001"..BuildUniqueValue(select(2,...))
end
end
--[[-----------------------------------------------------------------------------
Scripts
-------------------------------------------------------------------------------]]
local function Expand_OnClick(frame)
local button = frame.button
local self = button.obj
local status = (self.status or self.localstatus).groups
status[button.uniquevalue] = not status[button.uniquevalue]
self:RefreshTree()
end
local function Button_OnClick(frame)
local self = frame.obj
self:Fire("OnClick", frame.uniquevalue, frame.selected)
if not frame.selected then
self:SetSelected(frame.uniquevalue)
frame.selected = true
frame:LockHighlight()
self:RefreshTree()
end
AceGUI:ClearFocus()
end
local function Button_OnDoubleClick(button)
local self = button.obj
local status = (self.status or self.localstatus).groups
status[button.uniquevalue] = not status[button.uniquevalue]
self:RefreshTree()
end
local function Button_OnEnter(frame)
local self = frame.obj
self:Fire("OnButtonEnter", frame.uniquevalue, frame)
if self.enabletooltips then
local tooltip = AceGUI.tooltip
tooltip:SetOwner(frame, "ANCHOR_NONE")
tooltip:ClearAllPoints()
tooltip:SetPoint("LEFT",frame,"RIGHT")
tooltip:SetText(frame.text:GetText() or "", 1, .82, 0, 1, true)
tooltip:Show()
end
end
local function Button_OnLeave(frame)
local self = frame.obj
self:Fire("OnButtonLeave", frame.uniquevalue, frame)
if self.enabletooltips then
AceGUI.tooltip:Hide()
end
end
local function OnScrollValueChanged(frame, value)
if frame.obj.noupdate then return end
local self = frame.obj
local status = self.status or self.localstatus
status.scrollvalue = floor(value + 0.5)
self:RefreshTree()
AceGUI:ClearFocus()
end
local function Tree_OnSizeChanged(frame)
frame.obj:RefreshTree()
end
local function Tree_OnMouseWheel(frame, delta)
local self = frame.obj
if self.showscroll then
local scrollbar = self.scrollbar
local min, max = scrollbar:GetMinMaxValues()
local value = scrollbar:GetValue()
local newvalue = math_min(max,math_max(min,value - delta))
if value ~= newvalue then
scrollbar:SetValue(newvalue)
end
end
end
local function Dragger_OnLeave(frame)
frame:SetBackdropColor(1, 1, 1, 0)
end
local function Dragger_OnEnter(frame)
frame:SetBackdropColor(1, 1, 1, 0.8)
end
local function Dragger_OnMouseDown(frame)
local treeframe = frame:GetParent()
treeframe:StartSizing("RIGHT")
end
local function Dragger_OnMouseUp(frame)
local treeframe = frame:GetParent()
local self = treeframe.obj
local treeframeParent = treeframe:GetParent()
treeframe:StopMovingOrSizing()
--treeframe:SetScript("OnUpdate", nil)
treeframe:SetUserPlaced(false)
--Without this :GetHeight will get stuck on the current height, causing the tree contents to not resize
treeframe:SetHeight(0)
treeframe:ClearAllPoints()
treeframe:SetPoint("TOPLEFT", treeframeParent, "TOPLEFT",0,0)
treeframe:SetPoint("BOTTOMLEFT", treeframeParent, "BOTTOMLEFT",0,0)
local status = self.status or self.localstatus
status.treewidth = treeframe:GetWidth()
treeframe.obj:Fire("OnTreeResize",treeframe:GetWidth())
-- recalculate the content width
treeframe.obj:OnWidthSet(status.fullwidth)
-- update the layout of the content
treeframe.obj:DoLayout()
end
--[[-----------------------------------------------------------------------------
Methods
-------------------------------------------------------------------------------]]
local methods = {
["OnAcquire"] = function(self)
self:SetTreeWidth(DEFAULT_TREE_WIDTH, DEFAULT_TREE_SIZABLE)
self:EnableButtonTooltips(true)
self.frame:SetScript("OnUpdate", FirstFrameUpdate)
end,
["OnRelease"] = function(self)
self.status = nil
self.tree = nil
self.frame:SetScript("OnUpdate", nil)
for k, v in pairs(self.localstatus) do
if k == "groups" then
for k2 in pairs(v) do
v[k2] = nil
end
else
self.localstatus[k] = nil
end
end
self.localstatus.scrollvalue = 0
self.localstatus.treewidth = DEFAULT_TREE_WIDTH
self.localstatus.treesizable = DEFAULT_TREE_SIZABLE
end,
["EnableButtonTooltips"] = function(self, enable)
self.enabletooltips = enable
end,
["CreateButton"] = function(self)
local num = AceGUI:GetNextWidgetNum("TreeGroupButton")
local button = CreateFrame("Button", ("AceGUI30TreeButton%d"):format(num), self.treeframe, "OptionsListButtonTemplate")
button.obj = self
local icon = button:CreateTexture(nil, "OVERLAY")
icon:SetWidth(14)
icon:SetHeight(14)
button.icon = icon
button:SetScript("OnClick",Button_OnClick)
button:SetScript("OnDoubleClick", Button_OnDoubleClick)
button:SetScript("OnEnter",Button_OnEnter)
button:SetScript("OnLeave",Button_OnLeave)
button.toggle.button = button
button.toggle:SetScript("OnClick",Expand_OnClick)
button.text:SetHeight(14) -- Prevents text wrapping
return button
end,
["SetStatusTable"] = function(self, status)
assert(type(status) == "table")
self.status = status
if not status.groups then
status.groups = {}
end
if not status.scrollvalue then
status.scrollvalue = 0
end
if not status.treewidth then
status.treewidth = DEFAULT_TREE_WIDTH
end
if status.treesizable == nil then
status.treesizable = DEFAULT_TREE_SIZABLE
end
self:SetTreeWidth(status.treewidth,status.treesizable)
self:RefreshTree()
end,
--sets the tree to be displayed
["SetTree"] = function(self, tree, filter)
self.filter = filter
if tree then
assert(type(tree) == "table")
end
self.tree = tree
self:RefreshTree()
end,
["BuildLevel"] = function(self, tree, level, parent)
local groups = (self.status or self.localstatus).groups
for i, v in ipairs(tree) do
if v.children then
if not self.filter or ShouldDisplayLevel(v.children) then
local line = addLine(self, v, tree, level, parent)
if groups[line.uniquevalue] then
self:BuildLevel(v.children, level+1, line)
end
end
elseif v.visible ~= false or not self.filter then
addLine(self, v, tree, level, parent)
end
end
end,
["RefreshTree"] = function(self,scrollToSelection,fromOnUpdate)
local buttons = self.buttons
local lines = self.lines
while lines[1] do
local t = tremove(lines)
for k in pairs(t) do
t[k] = nil
end
del(t)
end
if not self.tree then return end
--Build the list of visible entries from the tree and status tables
local status = self.status or self.localstatus
local groupstatus = status.groups
local tree = self.tree
local treeframe = self.treeframe
status.scrollToSelection = status.scrollToSelection or scrollToSelection -- needs to be cached in case the control hasn't been drawn yet (code bails out below)
self:BuildLevel(tree, 1)
local numlines = #lines
local maxlines = (floor(((self.treeframe:GetHeight()or 0) - 20 ) / 18))
if maxlines <= 0 then return end
if self.frame:GetParent() == UIParent and not fromOnUpdate then
self.frame:SetScript("OnUpdate", FirstFrameUpdate)
return
end
local first, last
scrollToSelection = status.scrollToSelection
status.scrollToSelection = nil
if numlines <= maxlines then
--the whole tree fits in the frame
status.scrollvalue = 0
self:ShowScroll(false)
first, last = 1, numlines
else
self:ShowScroll(true)
--scrolling will be needed
self.noupdate = true
self.scrollbar:SetMinMaxValues(0, numlines - maxlines)
--check if we are scrolled down too far
if numlines - status.scrollvalue < maxlines then
status.scrollvalue = numlines - maxlines
end
self.noupdate = nil
first, last = status.scrollvalue+1, status.scrollvalue + maxlines
--show selection?
if scrollToSelection and status.selected then
local show
for i,line in ipairs(lines) do -- find the line number
if line.uniquevalue==status.selected then
show=i
end
end
if not show then
-- selection was deleted or something?
elseif show>=first and show<=last then
-- all good
else
-- scrolling needed!
if show<first then
status.scrollvalue = show-1
else
status.scrollvalue = show-maxlines
end
first, last = status.scrollvalue+1, status.scrollvalue + maxlines
end
end
if self.scrollbar:GetValue() ~= status.scrollvalue then
self.scrollbar:SetValue(status.scrollvalue)
end
end
local buttonnum = 1
for i = first, last do
local line = lines[i]
local button = buttons[buttonnum]
if not button then
button = self:CreateButton()
buttons[buttonnum] = button
button:SetParent(treeframe)
button:SetFrameLevel(treeframe:GetFrameLevel()+1)
button:ClearAllPoints()
if buttonnum == 1 then
if self.showscroll then
button:SetPoint("TOPRIGHT", -22, -10)
button:SetPoint("TOPLEFT", 0, -10)
else
button:SetPoint("TOPRIGHT", 0, -10)
button:SetPoint("TOPLEFT", 0, -10)
end
else
button:SetPoint("TOPRIGHT", buttons[buttonnum-1], "BOTTOMRIGHT",0,0)
button:SetPoint("TOPLEFT", buttons[buttonnum-1], "BOTTOMLEFT",0,0)
end
end
UpdateButton(button, line, status.selected == line.uniquevalue, line.hasChildren, groupstatus[line.uniquevalue] )
button:Show()
buttonnum = buttonnum + 1
end
-- We hide the remaining buttons after updating others to avoid a blizzard bug that keeps them interactable even if hidden when hidden before updating the buttons.
for i = buttonnum, #buttons do
buttons[i]:Hide()
end
end,
["SetSelected"] = function(self, value)
local status = self.status or self.localstatus
if status.selected ~= value then
status.selected = value
self:Fire("OnGroupSelected", value)
end
end,
["Select"] = function(self, uniquevalue, ...)
self.filter = false
local status = self.status or self.localstatus
local groups = status.groups
local path = {...}
for i = 1, #path do
groups[tconcat(path, "\001", 1, i)] = true
end
status.selected = uniquevalue
self:RefreshTree(true)
self:Fire("OnGroupSelected", uniquevalue)
end,
["SelectByPath"] = function(self, ...)
self:Select(BuildUniqueValue(...), ...)
end,
["SelectByValue"] = function(self, uniquevalue)
self:Select(uniquevalue, ("\001"):split(uniquevalue))
end,
["ShowScroll"] = function(self, show)
self.showscroll = show
if show then
self.scrollbar:Show()
if self.buttons[1] then
self.buttons[1]:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",-22,-10)
end
else
self.scrollbar:Hide()
if self.buttons[1] then
self.buttons[1]:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",0,-10)
end
end
end,
["OnWidthSet"] = function(self, width)
local content = self.content
local treeframe = self.treeframe
local status = self.status or self.localstatus
status.fullwidth = width
local contentwidth = width - status.treewidth - 20
if contentwidth < 0 then
contentwidth = 0
end
content:SetWidth(contentwidth)
content.width = contentwidth
local maxtreewidth = math_min(400, width - 50)
if maxtreewidth > 100 and status.treewidth > maxtreewidth then
self:SetTreeWidth(maxtreewidth, status.treesizable)
end
if treeframe.SetResizeBounds then
treeframe:SetResizeBounds(100, 1, maxtreewidth, 1600)
else
treeframe:SetMaxResize(maxtreewidth, 1600)
end
end,
["OnHeightSet"] = function(self, height)
local content = self.content
local contentheight = height - 20
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end,
["SetTreeWidth"] = function(self, treewidth, resizable)
if not resizable then
if type(treewidth) == 'number' then
resizable = false
elseif type(treewidth) == 'boolean' then
resizable = treewidth
treewidth = DEFAULT_TREE_WIDTH
else
resizable = false
treewidth = DEFAULT_TREE_WIDTH
end
end
self.treeframe:SetWidth(treewidth)
self.dragger:EnableMouse(resizable)
local status = self.status or self.localstatus
status.treewidth = treewidth
status.treesizable = resizable
-- recalculate the content width
if status.fullwidth then
self:OnWidthSet(status.fullwidth)
end
end,
["GetTreeWidth"] = function(self)
local status = self.status or self.localstatus
return status.treewidth or DEFAULT_TREE_WIDTH
end,
["LayoutFinished"] = function(self, width, height)
if self.noAutoHeight then return end
self:SetHeight((height or 0) + 20)
end
}
--[[-----------------------------------------------------------------------------
Constructor
-------------------------------------------------------------------------------]]
local PaneBackdrop = {
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 16,
insets = { left = 3, right = 3, top = 5, bottom = 3 }
}
local DraggerBackdrop = {
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
edgeFile = nil,
tile = true, tileSize = 16, edgeSize = 1,
insets = { left = 3, right = 3, top = 7, bottom = 7 }
}
local function Constructor()
local num = AceGUI:GetNextWidgetNum(Type)
local frame = CreateFrame("Frame", nil, UIParent)
local treeframe = CreateFrame("Frame", nil, frame, "BackdropTemplate")
treeframe:SetPoint("TOPLEFT")
treeframe:SetPoint("BOTTOMLEFT")
treeframe:SetWidth(DEFAULT_TREE_WIDTH)
treeframe:EnableMouseWheel(true)
treeframe:SetBackdrop(PaneBackdrop)
treeframe:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
treeframe:SetBackdropBorderColor(0.4, 0.4, 0.4)
treeframe:SetResizable(true)
if treeframe.SetResizeBounds then -- WoW 10.0
treeframe:SetResizeBounds(100, 1, 400, 1600)
else
treeframe:SetMinResize(100, 1)
treeframe:SetMaxResize(400, 1600)
end
treeframe:SetScript("OnUpdate", FirstFrameUpdate)
treeframe:SetScript("OnSizeChanged", Tree_OnSizeChanged)
treeframe:SetScript("OnMouseWheel", Tree_OnMouseWheel)
local dragger = CreateFrame("Frame", nil, treeframe, "BackdropTemplate")
dragger:SetWidth(8)
dragger:SetPoint("TOP", treeframe, "TOPRIGHT")
dragger:SetPoint("BOTTOM", treeframe, "BOTTOMRIGHT")
dragger:SetBackdrop(DraggerBackdrop)
dragger:SetBackdropColor(1, 1, 1, 0)
dragger:SetScript("OnEnter", Dragger_OnEnter)
dragger:SetScript("OnLeave", Dragger_OnLeave)
dragger:SetScript("OnMouseDown", Dragger_OnMouseDown)
dragger:SetScript("OnMouseUp", Dragger_OnMouseUp)
local scrollbar = CreateFrame("Slider", ("AceConfigDialogTreeGroup%dScrollBar"):format(num), treeframe, "UIPanelScrollBarTemplate")
scrollbar:SetScript("OnValueChanged", nil)
scrollbar:SetPoint("TOPRIGHT", -10, -26)
scrollbar:SetPoint("BOTTOMRIGHT", -10, 26)
scrollbar:SetMinMaxValues(0,0)
scrollbar:SetValueStep(1)
scrollbar:SetValue(0)
scrollbar:SetWidth(16)
scrollbar:SetScript("OnValueChanged", OnScrollValueChanged)
local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND")
scrollbg:SetAllPoints(scrollbar)
scrollbg:SetColorTexture(0,0,0,0.4)
local border = CreateFrame("Frame", nil, frame, "BackdropTemplate")
border:SetPoint("TOPLEFT", treeframe, "TOPRIGHT")
border:SetPoint("BOTTOMRIGHT")
border:SetBackdrop(PaneBackdrop)
border:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
border:SetBackdropBorderColor(0.4, 0.4, 0.4)
--Container Support
local content = CreateFrame("Frame", nil, border)
content:SetPoint("TOPLEFT", 10, -10)
content:SetPoint("BOTTOMRIGHT", -10, 10)
local widget = {
frame = frame,
lines = {},
levels = {},
buttons = {},
hasChildren = {},
localstatus = { groups = {}, scrollvalue = 0 },
filter = false,
treeframe = treeframe,
dragger = dragger,
scrollbar = scrollbar,
border = border,
content = content,
type = Type
}
for method, func in pairs(methods) do
widget[method] = func
end
treeframe.obj, dragger.obj, scrollbar.obj = widget, widget, widget
return AceGUI:RegisterAsContainer(widget)
end
AceGUI:RegisterWidgetType(Type, Constructor, Version)
@@ -1,328 +1,336 @@
local AceGUI = LibStub("AceGUI-3.0") local AceGUI = LibStub("AceGUI-3.0")
-- Lua APIs -- Lua APIs
local pairs, assert, type = pairs, assert, type local pairs, assert, type = pairs, assert, type
-- WoW APIs -- WoW APIs
local CreateFrame, UIParent = CreateFrame, UIParent local PlaySound = PlaySound
local CreateFrame, UIParent = CreateFrame, UIParent
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script ----------------
-- GLOBALS: GameFontNormal -- Main Frame --
----------------
---------------- --[[
-- Main Frame -- Events :
---------------- OnClose
--[[
Events : ]]
OnClose do
local Type = "Window"
]] local Version = 8
do
local Type = "Window" local function frameOnShow(this)
local Version = 2 this.obj:Fire("OnShow")
end
local function frameOnClose(this)
this.obj:Fire("OnClose") local function frameOnClose(this)
end this.obj:Fire("OnClose")
end
local function closeOnClick(this)
this.obj:Hide() local function closeOnClick(this)
end PlaySound(799) -- SOUNDKIT.GS_TITLE_OPTION_EXIT
this.obj:Hide()
local function frameOnMouseDown(this) end
AceGUI:ClearFocus()
end local function frameOnMouseDown(this)
AceGUI:ClearFocus()
local function titleOnMouseDown(this) end
this:GetParent():StartMoving()
AceGUI:ClearFocus() local function titleOnMouseDown(this)
end this:GetParent():StartMoving()
AceGUI:ClearFocus()
local function frameOnMouseUp(this) end
local frame = this:GetParent()
frame:StopMovingOrSizing() local function frameOnMouseUp(this)
local self = frame.obj local frame = this:GetParent()
local status = self.status or self.localstatus frame:StopMovingOrSizing()
status.width = frame:GetWidth() local self = frame.obj
status.height = frame:GetHeight() local status = self.status or self.localstatus
status.top = frame:GetTop() status.width = frame:GetWidth()
status.left = frame:GetLeft() status.height = frame:GetHeight()
end status.top = frame:GetTop()
status.left = frame:GetLeft()
local function sizerseOnMouseDown(this) end
this:GetParent():StartSizing("BOTTOMRIGHT")
AceGUI:ClearFocus() local function sizerseOnMouseDown(this)
end this:GetParent():StartSizing("BOTTOMRIGHT")
AceGUI:ClearFocus()
local function sizersOnMouseDown(this) end
this:GetParent():StartSizing("BOTTOM")
AceGUI:ClearFocus() local function sizersOnMouseDown(this)
end this:GetParent():StartSizing("BOTTOM")
AceGUI:ClearFocus()
local function sizereOnMouseDown(this) end
this:GetParent():StartSizing("RIGHT")
AceGUI:ClearFocus() local function sizereOnMouseDown(this)
end this:GetParent():StartSizing("RIGHT")
AceGUI:ClearFocus()
local function sizerOnMouseUp(this) end
this:GetParent():StopMovingOrSizing()
end local function sizerOnMouseUp(this)
this:GetParent():StopMovingOrSizing()
local function SetTitle(self,title) end
self.titletext:SetText(title)
end local function SetTitle(self,title)
self.titletext:SetText(title)
local function SetStatusText(self,text) end
-- self.statustext:SetText(text)
end local function SetStatusText(self,text)
-- self.statustext:SetText(text)
local function Hide(self) end
self.frame:Hide()
end local function Hide(self)
self.frame:Hide()
local function Show(self) end
self.frame:Show()
end local function Show(self)
self.frame:Show()
local function OnAcquire(self) end
self.frame:SetParent(UIParent)
self.frame:SetFrameStrata("FULLSCREEN_DIALOG") local function OnAcquire(self)
self:ApplyStatus() self.frame:SetParent(UIParent)
self:EnableResize(true) self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
end self:ApplyStatus()
self:EnableResize(true)
local function OnRelease(self) self:Show()
self.status = nil end
for k in pairs(self.localstatus) do
self.localstatus[k] = nil local function OnRelease(self)
end self.status = nil
end for k in pairs(self.localstatus) do
self.localstatus[k] = nil
-- called to set an external table to store status in end
local function SetStatusTable(self, status) end
assert(type(status) == "table")
self.status = status -- called to set an external table to store status in
self:ApplyStatus() local function SetStatusTable(self, status)
end assert(type(status) == "table")
self.status = status
local function ApplyStatus(self) self:ApplyStatus()
local status = self.status or self.localstatus end
local frame = self.frame
self:SetWidth(status.width or 700) local function ApplyStatus(self)
self:SetHeight(status.height or 500) local status = self.status or self.localstatus
if status.top and status.left then local frame = self.frame
frame:SetPoint("TOP",UIParent,"BOTTOM",0,status.top) self:SetWidth(status.width or 700)
frame:SetPoint("LEFT",UIParent,"LEFT",status.left,0) self:SetHeight(status.height or 500)
else if status.top and status.left then
frame:SetPoint("CENTER",UIParent,"CENTER") frame:SetPoint("TOP",UIParent,"BOTTOM",0,status.top)
end frame:SetPoint("LEFT",UIParent,"LEFT",status.left,0)
end else
frame:SetPoint("CENTER",UIParent,"CENTER")
local function OnWidthSet(self, width) end
local content = self.content end
local contentwidth = width - 34
if contentwidth < 0 then local function OnWidthSet(self, width)
contentwidth = 0 local content = self.content
end local contentwidth = width - 34
content:SetWidth(contentwidth) if contentwidth < 0 then
content.width = contentwidth contentwidth = 0
end end
content:SetWidth(contentwidth)
content.width = contentwidth
local function OnHeightSet(self, height) end
local content = self.content
local contentheight = height - 57
if contentheight < 0 then local function OnHeightSet(self, height)
contentheight = 0 local content = self.content
end local contentheight = height - 57
content:SetHeight(contentheight) if contentheight < 0 then
content.height = contentheight contentheight = 0
end end
content:SetHeight(contentheight)
local function EnableResize(self, state) content.height = contentheight
local func = state and "Show" or "Hide" end
self.sizer_se[func](self.sizer_se)
self.sizer_s[func](self.sizer_s) local function EnableResize(self, state)
self.sizer_e[func](self.sizer_e) local func = state and "Show" or "Hide"
end self.sizer_se[func](self.sizer_se)
self.sizer_s[func](self.sizer_s)
local function Constructor() self.sizer_e[func](self.sizer_e)
local frame = CreateFrame("Frame",nil,UIParent) end
local self = {}
self.type = "Window" local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
self.Hide = Hide local self = {}
self.Show = Show self.type = "Window"
self.SetTitle = SetTitle
self.OnRelease = OnRelease self.Hide = Hide
self.OnAcquire = OnAcquire self.Show = Show
self.SetStatusText = SetStatusText self.SetTitle = SetTitle
self.SetStatusTable = SetStatusTable self.OnRelease = OnRelease
self.ApplyStatus = ApplyStatus self.OnAcquire = OnAcquire
self.OnWidthSet = OnWidthSet self.SetStatusText = SetStatusText
self.OnHeightSet = OnHeightSet self.SetStatusTable = SetStatusTable
self.EnableResize = EnableResize self.ApplyStatus = ApplyStatus
self.OnWidthSet = OnWidthSet
self.localstatus = {} self.OnHeightSet = OnHeightSet
self.EnableResize = EnableResize
self.frame = frame
frame.obj = self self.localstatus = {}
frame:SetWidth(700)
frame:SetHeight(500) self.frame = frame
frame:SetPoint("CENTER",UIParent,"CENTER",0,0) frame.obj = self
frame:EnableMouse() frame:SetWidth(700)
frame:SetMovable(true) frame:SetHeight(500)
frame:SetResizable(true) frame:SetPoint("CENTER",UIParent,"CENTER",0,0)
frame:SetFrameStrata("FULLSCREEN_DIALOG") frame:EnableMouse()
frame:SetScript("OnMouseDown", frameOnMouseDown) frame:SetMovable(true)
frame:SetResizable(true)
frame:SetScript("OnHide",frameOnClose) frame:SetFrameStrata("FULLSCREEN_DIALOG")
frame:SetMinResize(240,240) frame:SetScript("OnMouseDown", frameOnMouseDown)
frame:SetToplevel(true)
frame:SetScript("OnShow",frameOnShow)
local titlebg = frame:CreateTexture(nil, "BACKGROUND") frame:SetScript("OnHide",frameOnClose)
titlebg:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Title-Background]]) if frame.SetResizeBounds then -- WoW 10.0
titlebg:SetPoint("TOPLEFT", 9, -6) frame:SetResizeBounds(240,240)
titlebg:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", -28, -24) else
frame:SetMinResize(240,240)
local dialogbg = frame:CreateTexture(nil, "BACKGROUND") end
dialogbg:SetTexture([[Interface\Tooltips\UI-Tooltip-Background]]) frame:SetToplevel(true)
dialogbg:SetPoint("TOPLEFT", 8, -24)
dialogbg:SetPoint("BOTTOMRIGHT", -6, 8) local titlebg = frame:CreateTexture(nil, "BACKGROUND")
dialogbg:SetVertexColor(0, 0, 0, .75) titlebg:SetTexture(251966) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Title-Background
titlebg:SetPoint("TOPLEFT", 9, -6)
local topleft = frame:CreateTexture(nil, "BORDER") titlebg:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", -28, -24)
topleft:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
topleft:SetWidth(64) local dialogbg = frame:CreateTexture(nil, "BACKGROUND")
topleft:SetHeight(64) dialogbg:SetTexture(137056) -- Interface\\Tooltips\\UI-Tooltip-Background
topleft:SetPoint("TOPLEFT") dialogbg:SetPoint("TOPLEFT", 8, -24)
topleft:SetTexCoord(0.501953125, 0.625, 0, 1) dialogbg:SetPoint("BOTTOMRIGHT", -6, 8)
dialogbg:SetVertexColor(0, 0, 0, .75)
local topright = frame:CreateTexture(nil, "BORDER")
topright:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) local topleft = frame:CreateTexture(nil, "BORDER")
topright:SetWidth(64) topleft:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
topright:SetHeight(64) topleft:SetWidth(64)
topright:SetPoint("TOPRIGHT") topleft:SetHeight(64)
topright:SetTexCoord(0.625, 0.75, 0, 1) topleft:SetPoint("TOPLEFT")
topleft:SetTexCoord(0.501953125, 0.625, 0, 1)
local top = frame:CreateTexture(nil, "BORDER")
top:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) local topright = frame:CreateTexture(nil, "BORDER")
top:SetHeight(64) topright:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
top:SetPoint("TOPLEFT", topleft, "TOPRIGHT") topright:SetWidth(64)
top:SetPoint("TOPRIGHT", topright, "TOPLEFT") topright:SetHeight(64)
top:SetTexCoord(0.25, 0.369140625, 0, 1) topright:SetPoint("TOPRIGHT")
topright:SetTexCoord(0.625, 0.75, 0, 1)
local bottomleft = frame:CreateTexture(nil, "BORDER")
bottomleft:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) local top = frame:CreateTexture(nil, "BORDER")
bottomleft:SetWidth(64) top:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
bottomleft:SetHeight(64) top:SetHeight(64)
bottomleft:SetPoint("BOTTOMLEFT") top:SetPoint("TOPLEFT", topleft, "TOPRIGHT")
bottomleft:SetTexCoord(0.751953125, 0.875, 0, 1) top:SetPoint("TOPRIGHT", topright, "TOPLEFT")
top:SetTexCoord(0.25, 0.369140625, 0, 1)
local bottomright = frame:CreateTexture(nil, "BORDER")
bottomright:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) local bottomleft = frame:CreateTexture(nil, "BORDER")
bottomright:SetWidth(64) bottomleft:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
bottomright:SetHeight(64) bottomleft:SetWidth(64)
bottomright:SetPoint("BOTTOMRIGHT") bottomleft:SetHeight(64)
bottomright:SetTexCoord(0.875, 1, 0, 1) bottomleft:SetPoint("BOTTOMLEFT")
bottomleft:SetTexCoord(0.751953125, 0.875, 0, 1)
local bottom = frame:CreateTexture(nil, "BORDER")
bottom:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) local bottomright = frame:CreateTexture(nil, "BORDER")
bottom:SetHeight(64) bottomright:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
bottom:SetPoint("BOTTOMLEFT", bottomleft, "BOTTOMRIGHT") bottomright:SetWidth(64)
bottom:SetPoint("BOTTOMRIGHT", bottomright, "BOTTOMLEFT") bottomright:SetHeight(64)
bottom:SetTexCoord(0.376953125, 0.498046875, 0, 1) bottomright:SetPoint("BOTTOMRIGHT")
bottomright:SetTexCoord(0.875, 1, 0, 1)
local left = frame:CreateTexture(nil, "BORDER")
left:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) local bottom = frame:CreateTexture(nil, "BORDER")
left:SetWidth(64) bottom:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
left:SetPoint("TOPLEFT", topleft, "BOTTOMLEFT") bottom:SetHeight(64)
left:SetPoint("BOTTOMLEFT", bottomleft, "TOPLEFT") bottom:SetPoint("BOTTOMLEFT", bottomleft, "BOTTOMRIGHT")
left:SetTexCoord(0.001953125, 0.125, 0, 1) bottom:SetPoint("BOTTOMRIGHT", bottomright, "BOTTOMLEFT")
bottom:SetTexCoord(0.376953125, 0.498046875, 0, 1)
local right = frame:CreateTexture(nil, "BORDER")
right:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) local left = frame:CreateTexture(nil, "BORDER")
right:SetWidth(64) left:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
right:SetPoint("TOPRIGHT", topright, "BOTTOMRIGHT") left:SetWidth(64)
right:SetPoint("BOTTOMRIGHT", bottomright, "TOPRIGHT") left:SetPoint("TOPLEFT", topleft, "BOTTOMLEFT")
right:SetTexCoord(0.1171875, 0.2421875, 0, 1) left:SetPoint("BOTTOMLEFT", bottomleft, "TOPLEFT")
left:SetTexCoord(0.001953125, 0.125, 0, 1)
local close = CreateFrame("Button", nil, frame, "UIPanelCloseButton")
close:SetPoint("TOPRIGHT", 2, 1) local right = frame:CreateTexture(nil, "BORDER")
close:SetScript("OnClick", closeOnClick) right:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
self.closebutton = close right:SetWidth(64)
close.obj = self right:SetPoint("TOPRIGHT", topright, "BOTTOMRIGHT")
right:SetPoint("BOTTOMRIGHT", bottomright, "TOPRIGHT")
local titletext = frame:CreateFontString(nil, "ARTWORK") right:SetTexCoord(0.1171875, 0.2421875, 0, 1)
titletext:SetFontObject(GameFontNormal)
titletext:SetPoint("TOPLEFT", 12, -8) local close = CreateFrame("Button", nil, frame, "UIPanelCloseButton")
titletext:SetPoint("TOPRIGHT", -32, -8) close:SetPoint("TOPRIGHT", 2, 1)
self.titletext = titletext close:SetScript("OnClick", closeOnClick)
self.closebutton = close
local title = CreateFrame("Button", nil, frame) close.obj = self
title:SetPoint("TOPLEFT", titlebg)
title:SetPoint("BOTTOMRIGHT", titlebg) local titletext = frame:CreateFontString(nil, "ARTWORK")
title:EnableMouse() titletext:SetFontObject(GameFontNormal)
title:SetScript("OnMouseDown",titleOnMouseDown) titletext:SetPoint("TOPLEFT", 12, -8)
title:SetScript("OnMouseUp", frameOnMouseUp) titletext:SetPoint("TOPRIGHT", -32, -8)
self.title = title self.titletext = titletext
local sizer_se = CreateFrame("Frame",nil,frame) local title = CreateFrame("Button", nil, frame)
sizer_se:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0) title:SetPoint("TOPLEFT", titlebg)
sizer_se:SetWidth(25) title:SetPoint("BOTTOMRIGHT", titlebg)
sizer_se:SetHeight(25) title:EnableMouse()
sizer_se:EnableMouse() title:SetScript("OnMouseDown",titleOnMouseDown)
sizer_se:SetScript("OnMouseDown",sizerseOnMouseDown) title:SetScript("OnMouseUp", frameOnMouseUp)
sizer_se:SetScript("OnMouseUp", sizerOnMouseUp) self.title = title
self.sizer_se = sizer_se
local sizer_se = CreateFrame("Frame",nil,frame)
local line1 = sizer_se:CreateTexture(nil, "BACKGROUND") sizer_se:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
self.line1 = line1 sizer_se:SetWidth(25)
line1:SetWidth(14) sizer_se:SetHeight(25)
line1:SetHeight(14) sizer_se:EnableMouse()
line1:SetPoint("BOTTOMRIGHT", -8, 8) sizer_se:SetScript("OnMouseDown",sizerseOnMouseDown)
line1:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border") sizer_se:SetScript("OnMouseUp", sizerOnMouseUp)
local x = 0.1 * 14/17 self.sizer_se = sizer_se
line1:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
local line1 = sizer_se:CreateTexture(nil, "BACKGROUND")
local line2 = sizer_se:CreateTexture(nil, "BACKGROUND") self.line1 = line1
self.line2 = line2 line1:SetWidth(14)
line2:SetWidth(8) line1:SetHeight(14)
line2:SetHeight(8) line1:SetPoint("BOTTOMRIGHT", -8, 8)
line2:SetPoint("BOTTOMRIGHT", -8, 8) line1:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border
line2:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border") local x = 0.1 * 14/17
local x = 0.1 * 8/17 line1:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
line2:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
local line2 = sizer_se:CreateTexture(nil, "BACKGROUND")
local sizer_s = CreateFrame("Frame",nil,frame) self.line2 = line2
sizer_s:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-25,0) line2:SetWidth(8)
sizer_s:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,0) line2:SetHeight(8)
sizer_s:SetHeight(25) line2:SetPoint("BOTTOMRIGHT", -8, 8)
sizer_s:EnableMouse() line2:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border
sizer_s:SetScript("OnMouseDown",sizersOnMouseDown) x = 0.1 * 8/17
sizer_s:SetScript("OnMouseUp", sizerOnMouseUp) line2:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
self.sizer_s = sizer_s
local sizer_s = CreateFrame("Frame",nil,frame)
local sizer_e = CreateFrame("Frame",nil,frame) sizer_s:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-25,0)
sizer_e:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,25) sizer_s:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,0)
sizer_e:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0) sizer_s:SetHeight(25)
sizer_e:SetWidth(25) sizer_s:EnableMouse()
sizer_e:EnableMouse() sizer_s:SetScript("OnMouseDown",sizersOnMouseDown)
sizer_e:SetScript("OnMouseDown",sizereOnMouseDown) sizer_s:SetScript("OnMouseUp", sizerOnMouseUp)
sizer_e:SetScript("OnMouseUp", sizerOnMouseUp) self.sizer_s = sizer_s
self.sizer_e = sizer_e
local sizer_e = CreateFrame("Frame",nil,frame)
--Container Support sizer_e:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,25)
local content = CreateFrame("Frame",nil,frame) sizer_e:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
self.content = content sizer_e:SetWidth(25)
content.obj = self sizer_e:EnableMouse()
content:SetPoint("TOPLEFT",frame,"TOPLEFT",12,-32) sizer_e:SetScript("OnMouseDown",sizereOnMouseDown)
content:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-12,13) sizer_e:SetScript("OnMouseUp", sizerOnMouseUp)
self.sizer_e = sizer_e
AceGUI:RegisterAsContainer(self)
return self --Container Support
end local content = CreateFrame("Frame",nil,frame)
self.content = content
AceGUI:RegisterWidgetType(Type,Constructor,Version) content.obj = self
end content:SetPoint("TOPLEFT",frame,"TOPLEFT",12,-32)
content:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-12,13)
AceGUI:RegisterAsContainer(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
@@ -1,153 +0,0 @@
local AceGUI = LibStub("AceGUI-3.0")
-------------
-- Widgets --
-------------
--[[
Widgets must provide the following functions
Acquire() - Called when the object is aquired, should set everything to a default hidden state
Release() - Called when the object is Released, should remove any anchors and hide the Widget
And the following members
frame - the frame or derivitive object that will be treated as the widget for size and anchoring purposes
type - the type of the object, same as the name given to :RegisterWidget()
Widgets contain a table called userdata, this is a safe place to store data associated with the wigdet
It will be cleared automatically when a widget is released
Placing values directly into a widget object should be avoided
If the Widget can act as a container for other Widgets the following
content - frame or derivitive that children will be anchored to
The Widget can supply the following Optional Members
]]
----------------------------------
-- Blizzard Options Group --
----------------------------------
--[[
Group Designed to be added to the bliz interface options panel
]]
-- WoW APIs
local CreateFrame = CreateFrame
do
local Type = "BlizOptionsGroup"
local Version = 10
local function OnAcquire(self)
end
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
self:SetName()
end
local function okay(this)
this.obj:Fire("okay")
end
local function cancel(this)
this.obj:Fire("cancel")
end
local function defaults(this)
this.obj:Fire("defaults")
end
local function SetName(self, name, parent)
self.frame.name = name
self.frame.parent = parent
end
local function OnShow(this)
this.obj:Fire("OnShow")
end
local function OnHide(this)
this.obj:Fire("OnHide")
end
local function OnWidthSet(self, width)
local content = self.content
local contentwidth = width - 63
if contentwidth < 0 then
contentwidth = 0
end
content:SetWidth(contentwidth)
content.width = contentwidth
end
local function OnHeightSet(self, height)
local content = self.content
local contentheight = height - 26
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end
local function SetTitle(self, title)
local content = self.content
content:ClearAllPoints()
if not title or title == "" then
content:SetPoint("TOPLEFT",self.frame,"TOPLEFT",10,-10)
self.label:SetText("")
else
content:SetPoint("TOPLEFT",self.frame,"TOPLEFT",10,-40)
self.label:SetText(title)
end
content:SetPoint("BOTTOMRIGHT",self.frame,"BOTTOMRIGHT",-10,10)
end
local function Constructor()
local frame = CreateFrame("Frame")
local self = {}
self.type = Type
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.frame = frame
self.SetName = SetName
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
self.SetTitle = SetTitle
frame.obj = self
frame.okay = okay
frame.cancel = cancel
frame.defaults = defaults
frame:Hide()
frame:SetScript("OnHide",OnHide)
frame:SetScript("OnShow",OnShow)
local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormalLarge")
self.label = label
label:SetPoint("TOPLEFT", frame, "TOPLEFT", 10, -15)
label:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", 10, -45)
label:SetJustifyH("LEFT")
label:SetJustifyV("TOP")
--Container Support
local content = CreateFrame("Frame",nil,frame)
self.content = content
content.obj = self
content:SetPoint("TOPLEFT",frame,"TOPLEFT",15,-10)
content:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-10,10)
AceGUI:RegisterAsContainer(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
+103 -104
View File
@@ -1,104 +1,103 @@
local AceGUI = LibStub("AceGUI-3.0") --[[-----------------------------------------------------------------------------
Button Widget
-- WoW APIs Graphical Button.
local _G = _G -------------------------------------------------------------------------------]]
local CreateFrame, UIParent = CreateFrame, UIParent local Type, Version = "Button", 24
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
-------------------------- if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
-- Button --
-------------------------- -- Lua APIs
do local pairs = pairs
local Type = "Button"
local Version = 12 -- WoW APIs
local _G = _G
local function OnAcquire(self) local PlaySound, CreateFrame, UIParent = PlaySound, CreateFrame, UIParent
-- restore default values
self:SetHeight(24) --[[-----------------------------------------------------------------------------
self:SetWidth(200) Scripts
end -------------------------------------------------------------------------------]]
local function Button_OnClick(frame, ...)
local function OnRelease(self) AceGUI:ClearFocus()
self.frame:ClearAllPoints() PlaySound(852) -- SOUNDKIT.IG_MAINMENU_OPTION
self.frame:Hide() frame.obj:Fire("OnClick", ...)
self:SetDisabled(false) end
end
local function Control_OnEnter(frame)
local function Button_OnClick(this, ...) frame.obj:Fire("OnEnter")
this.obj:Fire("OnClick", ...) end
AceGUI:ClearFocus()
end local function Control_OnLeave(frame)
frame.obj:Fire("OnLeave")
local function Button_OnEnter(this) end
this.obj:Fire("OnEnter")
end --[[-----------------------------------------------------------------------------
Methods
local function Button_OnLeave(this) -------------------------------------------------------------------------------]]
this.obj:Fire("OnLeave") local methods = {
end ["OnAcquire"] = function(self)
-- restore default values
local function SetText(self, text) self:SetHeight(24)
self.text:SetText(text or "") self:SetWidth(200)
end self:SetDisabled(false)
self:SetAutoWidth(false)
local function SetDisabled(self, disabled) self:SetText()
self.disabled = disabled end,
if disabled then
self.frame:Disable() -- ["OnRelease"] = nil,
else
self.frame:Enable() ["SetText"] = function(self, text)
end self.text:SetText(text)
end if self.autoWidth then
self:SetWidth(self.text:GetStringWidth() + 30)
local function Constructor() end
local num = AceGUI:GetNextWidgetNum(Type) end,
local name = "AceGUI30Button"..num
local frame = CreateFrame("Button",name,UIParent,"UIPanelButtonTemplate2") ["SetAutoWidth"] = function(self, autoWidth)
local self = {} self.autoWidth = autoWidth
self.num = num if self.autoWidth then
self.type = Type self:SetWidth(self.text:GetStringWidth() + 30)
self.frame = frame end
end,
local left = _G[name .. "Left"]
local right = _G[name .. "Right"] ["SetDisabled"] = function(self, disabled)
local middle = _G[name .. "Middle"] self.disabled = disabled
if disabled then
left:SetPoint("TOP", frame, "TOP", 0, 0) self.frame:Disable()
left:SetPoint("BOTTOM", frame, "BOTTOM", 0, 0) else
self.frame:Enable()
right:SetPoint("TOP", frame, "TOP", 0, 0) end
right:SetPoint("BOTTOM", frame, "BOTTOM", 0, 0) end
}
middle:SetPoint("TOP", frame, "TOP", 0, 0)
middle:SetPoint("BOTTOM", frame, "BOTTOM", 0, 0) --[[-----------------------------------------------------------------------------
Constructor
local text = frame:GetFontString() -------------------------------------------------------------------------------]]
self.text = text local function Constructor()
text:ClearAllPoints() local name = "AceGUI30Button" .. AceGUI:GetNextWidgetNum(Type)
text:SetPoint("TOPLEFT",frame,"TOPLEFT", 15, -1) local frame = CreateFrame("Button", name, UIParent, "UIPanelButtonTemplate")
text:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT", -15, 1) frame:Hide()
text:SetJustifyV("MIDDLE")
frame:EnableMouse(true)
frame:SetScript("OnClick",Button_OnClick) frame:SetScript("OnClick", Button_OnClick)
frame:SetScript("OnEnter",Button_OnEnter) frame:SetScript("OnEnter", Control_OnEnter)
frame:SetScript("OnLeave",Button_OnLeave) frame:SetScript("OnLeave", Control_OnLeave)
self.SetText = SetText local text = frame:GetFontString()
self.SetDisabled = SetDisabled text:ClearAllPoints()
text:SetPoint("TOPLEFT", 15, -1)
frame:EnableMouse(true) text:SetPoint("BOTTOMRIGHT", -15, 1)
text:SetJustifyV("MIDDLE")
frame:SetHeight(24)
frame:SetWidth(200) local widget = {
text = text,
self.OnRelease = OnRelease frame = frame,
self.OnAcquire = OnAcquire type = Type
}
self.frame = frame for method, func in pairs(methods) do
frame.obj = self widget[method] = func
end
AceGUI:RegisterAsWidget(self)
return self return AceGUI:RegisterAsWidget(widget)
end end
AceGUI:RegisterWidgetType(Type,Constructor,Version) AceGUI:RegisterWidgetType(Type, Constructor, Version)
end
+292 -300
View File
@@ -1,300 +1,292 @@
local AceGUI = LibStub("AceGUI-3.0") --[[-----------------------------------------------------------------------------
Checkbox Widget
-- Lua APIs -------------------------------------------------------------------------------]]
local select = select local Type, Version = "CheckBox", 26
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
-- WoW APIs if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
local CreateFrame, UIParent = CreateFrame, UIParent
-- Lua APIs
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded local select, pairs = select, pairs
-- List them here for Mikk's FindGlobals script
-- GLOBALS: SetDesaturation, GameFontHighlight -- WoW APIs
local PlaySound = PlaySound
-------------------------- local CreateFrame, UIParent = CreateFrame, UIParent
-- Check Box --
-------------------------- --[[-----------------------------------------------------------------------------
--[[ Support functions
Events : -------------------------------------------------------------------------------]]
OnValueChanged local function AlignImage(self)
local img = self.image:GetTexture()
]] self.text:ClearAllPoints()
do if not img then
local Type = "CheckBox" self.text:SetPoint("LEFT", self.checkbg, "RIGHT")
local Version = 13 self.text:SetPoint("RIGHT")
else
local function OnAcquire(self) self.text:SetPoint("LEFT", self.image, "RIGHT", 1, 0)
self:SetValue(false) self.text:SetPoint("RIGHT")
self.tristate = nil end
self:SetHeight(24) end
self:SetWidth(200)
self:SetImage() --[[-----------------------------------------------------------------------------
end Scripts
-------------------------------------------------------------------------------]]
local function OnRelease(self) local function Control_OnEnter(frame)
self.frame:ClearAllPoints() frame.obj:Fire("OnEnter")
self.frame:Hide() end
self.check:Hide()
self.highlight:Hide() local function Control_OnLeave(frame)
self.down = nil frame.obj:Fire("OnLeave")
self.checked = nil end
self:SetType()
self:SetDisabled(false) local function CheckBox_OnMouseDown(frame)
self:SetDescription(nil) local self = frame.obj
end if not self.disabled then
if self.image:GetTexture() then
local function CheckBox_OnEnter(this) self.text:SetPoint("LEFT", self.image,"RIGHT", 2, -1)
local self = this.obj else
self.highlight:Show() self.text:SetPoint("LEFT", self.checkbg, "RIGHT", 1, -1)
self:Fire("OnEnter") end
end end
AceGUI:ClearFocus()
local function CheckBox_OnLeave(this) end
local self = this.obj
self.highlight:Hide() local function CheckBox_OnMouseUp(frame)
self:Fire("OnLeave") local self = frame.obj
end if not self.disabled then
self:ToggleChecked()
local function CheckBox_OnMouseUp(this)
local self = this.obj if self.checked then
if not self.disabled then PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
self:ToggleChecked() else -- for both nil and false (tristate)
self:Fire("OnValueChanged",self.checked) PlaySound(857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF
self.text:SetPoint("LEFT",self.check,"RIGHT",0,0) end
end
self.down = nil self:Fire("OnValueChanged", self.checked)
end AlignImage(self)
end
local function CheckBox_OnMouseDown(this) end
local self = this.obj
if not self.disabled then --[[-----------------------------------------------------------------------------
self.text:SetPoint("LEFT",self.check,"RIGHT",1,-1) Methods
self.down = true -------------------------------------------------------------------------------]]
end local methods = {
AceGUI:ClearFocus() ["OnAcquire"] = function(self)
end self:SetType()
self:SetValue(false)
local function SetDisabled(self,disabled) self:SetTriState(nil)
self.disabled = disabled -- height is calculated from the width and required space for the description
if disabled then self:SetWidth(200)
self.frame:Disable() self:SetImage()
self.text:SetTextColor(0.5,0.5,0.5) self:SetDisabled(nil)
SetDesaturation(self.check, true) self:SetDescription(nil)
else end,
self.frame:Enable()
self.text:SetTextColor(1,1,1) -- ["OnRelease"] = nil,
if self.tristate and self.checked == nil then
SetDesaturation(self.check, true) ["OnWidthSet"] = function(self, width)
else if self.desc then
SetDesaturation(self.check, false) self.desc:SetWidth(width - 30)
end if self.desc:GetText() and self.desc:GetText() ~= "" then
end self:SetHeight(28 + self.desc:GetStringHeight())
end end
end
local function SetValue(self,value) end,
local check = self.check
self.checked = value ["SetDisabled"] = function(self, disabled)
if value then self.disabled = disabled
SetDesaturation(self.check, false) if disabled then
self.check:Show() self.frame:Disable()
else self.text:SetTextColor(0.5, 0.5, 0.5)
--Nil is the unknown tristate value SetDesaturation(self.check, true)
if self.tristate and value == nil then if self.desc then
SetDesaturation(self.check, true) self.desc:SetTextColor(0.5, 0.5, 0.5)
self.check:Show() end
else else
SetDesaturation(self.check, false) self.frame:Enable()
self.check:Hide() self.text:SetTextColor(1, 1, 1)
end if self.tristate and self.checked == nil then
end SetDesaturation(self.check, true)
end else
SetDesaturation(self.check, false)
local function SetTriState(self, enabled) end
self.tristate = enabled if self.desc then
self:SetValue(self:GetValue()) self.desc:SetTextColor(1, 1, 1)
end end
end
local function GetValue(self) end,
return self.checked
end ["SetValue"] = function(self, value)
local check = self.check
local function SetType(self, type) self.checked = value
local checkbg = self.checkbg if value then
local check = self.check SetDesaturation(check, false)
local highlight = self.highlight check:Show()
else
if type == "radio" then --Nil is the unknown tristate value
checkbg:SetHeight(16) if self.tristate and value == nil then
checkbg:SetWidth(16) SetDesaturation(check, true)
checkbg:SetTexture("Interface\\Buttons\\UI-RadioButton") check:Show()
checkbg:SetTexCoord(0,0.25,0,1) else
check:SetHeight(16) SetDesaturation(check, false)
check:SetWidth(16) check:Hide()
check:SetTexture("Interface\\Buttons\\UI-RadioButton") end
check:SetTexCoord(0.25,0.5,0,1) end
check:SetBlendMode("ADD") self:SetDisabled(self.disabled)
highlight:SetTexture("Interface\\Buttons\\UI-RadioButton") end,
highlight:SetTexCoord(0.5,0.75,0,1)
else ["GetValue"] = function(self)
checkbg:SetHeight(24) return self.checked
checkbg:SetWidth(24) end,
checkbg:SetTexture("Interface\\Buttons\\UI-CheckBox-Up")
checkbg:SetTexCoord(0,1,0,1) ["SetTriState"] = function(self, enabled)
check:SetHeight(24) self.tristate = enabled
check:SetWidth(24) self:SetValue(self:GetValue())
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check") end,
check:SetTexCoord(0,1,0,1)
check:SetBlendMode("BLEND") ["SetType"] = function(self, type)
highlight:SetTexture("Interface\\Buttons\\UI-CheckBox-Highlight") local checkbg = self.checkbg
highlight:SetTexCoord(0,1,0,1) local check = self.check
end local highlight = self.highlight
end
local size
local function ToggleChecked(self) if type == "radio" then
local value = self:GetValue() size = 16
if self.tristate then checkbg:SetTexture(130843) -- Interface\\Buttons\\UI-RadioButton
--cycle in true, nil, false order checkbg:SetTexCoord(0, 0.25, 0, 1)
if value then check:SetTexture(130843) -- Interface\\Buttons\\UI-RadioButton
self:SetValue(nil) check:SetTexCoord(0.25, 0.5, 0, 1)
elseif value == nil then check:SetBlendMode("ADD")
self:SetValue(false) highlight:SetTexture(130843) -- Interface\\Buttons\\UI-RadioButton
else highlight:SetTexCoord(0.5, 0.75, 0, 1)
self:SetValue(true) else
end size = 24
else checkbg:SetTexture(130755) -- Interface\\Buttons\\UI-CheckBox-Up
self:SetValue(not self:GetValue()) checkbg:SetTexCoord(0, 1, 0, 1)
end check:SetTexture(130751) -- Interface\\Buttons\\UI-CheckBox-Check
end check:SetTexCoord(0, 1, 0, 1)
check:SetBlendMode("BLEND")
local function SetLabel(self, label) highlight:SetTexture(130753) -- Interface\\Buttons\\UI-CheckBox-Highlight
self.text:SetText(label) highlight:SetTexCoord(0, 1, 0, 1)
end end
checkbg:SetHeight(size)
local function SetDescription(self, desc) checkbg:SetWidth(size)
if desc then end,
if not self.desc then
local desc = self.frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall") ["ToggleChecked"] = function(self)
desc:ClearAllPoints() local value = self:GetValue()
desc:SetPoint("TOPLEFT", self.check, "TOPRIGHT", 5, -21) if self.tristate then
desc:SetWidth(self.frame.width - 30) --cycle in true, nil, false order
desc:SetJustifyH("LEFT") if value then
desc:SetJustifyV("TOP") self:SetValue(nil)
self.desc = desc elseif value == nil then
end self:SetValue(false)
self.desc:Show() else
--self.text:SetFontObject(GameFontNormal) self:SetValue(true)
self.desc:SetText(desc) end
self:SetHeight(28 + self.desc:GetHeight()) else
else self:SetValue(not self:GetValue())
if self.desc then end
self.desc:SetText("") end,
self.desc:Hide()
end ["SetLabel"] = function(self, label)
self.text:SetFontObject(GameFontHighlight) self.text:SetText(label)
self:SetHeight(24) end,
end
end ["SetDescription"] = function(self, desc)
if desc then
local function SetImage(self, path, ...) if not self.desc then
local image = self.image local f = self.frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
image:SetTexture(path) f:ClearAllPoints()
f:SetPoint("TOPLEFT", self.checkbg, "TOPRIGHT", 5, -21)
if image:GetTexture() then f:SetWidth(self.frame.width - 30)
local n = select('#', ...) f:SetPoint("RIGHT", self.frame, "RIGHT", -30, 0)
if n == 4 or n == 8 then f:SetJustifyH("LEFT")
image:SetTexCoord(...) f:SetJustifyV("TOP")
else self.desc = f
image:SetTexCoord(0, 1, 0, 1) end
end self.desc:Show()
end --self.text:SetFontObject(GameFontNormal)
self:AlignImage() self.desc:SetText(desc)
end self:SetHeight(28 + self.desc:GetStringHeight())
else
local function AlignImage(self) if self.desc then
local img = self.image:GetTexture() self.desc:SetText("")
self.text:ClearAllPoints() self.desc:Hide()
if not img then end
self.text:SetPoint("LEFT", self.check, "RIGHT", 0, 0) --self.text:SetFontObject(GameFontHighlight)
self.text:SetPoint("RIGHT", self.frame, "RIGHT", 0, 0) self:SetHeight(24)
else end
self.text:SetPoint("LEFT", self.image,"RIGHT", 1, 0) end,
self.text:SetPoint("RIGHT", self.frame,"RIGHT", 0, 0)
end ["SetImage"] = function(self, path, ...)
end local image = self.image
image:SetTexture(path)
local function OnWidthSet(self, width)
if self.desc and self.desc:GetText() ~= "" then if image:GetTexture() then
self.desc:SetWidth(width - 30) local n = select("#", ...)
self:SetHeight(28 + self.desc:GetHeight()) if n == 4 or n == 8 then
end image:SetTexCoord(...)
end else
image:SetTexCoord(0, 1, 0, 1)
local function Constructor() end
local frame = CreateFrame("Button",nil,UIParent) end
local self = {} AlignImage(self)
self.type = Type end
}
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire --[[-----------------------------------------------------------------------------
Constructor
self.SetValue = SetValue -------------------------------------------------------------------------------]]
self.GetValue = GetValue local function Constructor()
self.SetDisabled = SetDisabled local frame = CreateFrame("Button", nil, UIParent)
self.SetType = SetType frame:Hide()
self.ToggleChecked = ToggleChecked
self.SetLabel = SetLabel frame:EnableMouse(true)
self.SetTriState = SetTriState frame:SetScript("OnEnter", Control_OnEnter)
self.SetDescription = SetDescription frame:SetScript("OnLeave", Control_OnLeave)
self.OnWidthSet = OnWidthSet frame:SetScript("OnMouseDown", CheckBox_OnMouseDown)
self.SetImage = SetImage frame:SetScript("OnMouseUp", CheckBox_OnMouseUp)
self.AlignImage = AlignImage
local checkbg = frame:CreateTexture(nil, "ARTWORK")
self.frame = frame checkbg:SetWidth(24)
frame.obj = self checkbg:SetHeight(24)
checkbg:SetPoint("TOPLEFT")
local text = frame:CreateFontString(nil,"OVERLAY","GameFontHighlight") checkbg:SetTexture(130755) -- Interface\\Buttons\\UI-CheckBox-Up
self.text = text
local check = frame:CreateTexture(nil, "OVERLAY")
frame:SetScript("OnEnter",CheckBox_OnEnter) check:SetAllPoints(checkbg)
frame:SetScript("OnLeave",CheckBox_OnLeave) check:SetTexture(130751) -- Interface\\Buttons\\UI-CheckBox-Check
frame:SetScript("OnMouseUp",CheckBox_OnMouseUp)
frame:SetScript("OnMouseDown",CheckBox_OnMouseDown) local text = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
frame:EnableMouse() text:SetJustifyH("LEFT")
local checkbg = frame:CreateTexture(nil,"ARTWORK") text:SetHeight(18)
self.checkbg = checkbg text:SetPoint("LEFT", checkbg, "RIGHT")
checkbg:SetWidth(24) text:SetPoint("RIGHT")
checkbg:SetHeight(24)
checkbg:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0) local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
checkbg:SetTexture("Interface\\Buttons\\UI-CheckBox-Up") highlight:SetTexture(130753) -- Interface\\Buttons\\UI-CheckBox-Highlight
local check = frame:CreateTexture(nil,"OVERLAY") highlight:SetBlendMode("ADD")
self.check = check highlight:SetAllPoints(checkbg)
check:SetWidth(24)
check:SetHeight(24) local image = frame:CreateTexture(nil, "OVERLAY")
check:SetPoint("CENTER",checkbg,"CENTER",0,0) image:SetHeight(16)
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check") image:SetWidth(16)
image:SetPoint("LEFT", checkbg, "RIGHT", 1, 0)
local highlight = frame:CreateTexture(nil, "OVERLAY")
self.highlight = highlight local widget = {
highlight:SetTexture("Interface\\Buttons\\UI-CheckBox-Highlight") checkbg = checkbg,
highlight:SetBlendMode("ADD") check = check,
highlight:SetAllPoints(checkbg) text = text,
highlight:Hide() highlight = highlight,
image = image,
local image = frame:CreateTexture(nil, "OVERLAY") frame = frame,
self.image = image type = Type
image:SetHeight(16) }
image:SetWidth(16) for method, func in pairs(methods) do
image:SetPoint("LEFT", check, "RIGHT", 1, 0) widget[method] = func
end
text:SetJustifyH("LEFT")
frame:SetHeight(24) return AceGUI:RegisterAsWidget(widget)
frame:SetWidth(200) end
text:SetHeight(18)
text:SetPoint("LEFT",check,"RIGHT",0,0) AceGUI:RegisterWidgetType(Type, Constructor, Version)
text:SetPoint("RIGHT",frame,"RIGHT",0,0)
AceGUI:RegisterAsWidget(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
@@ -1,181 +1,230 @@
local AceGUI = LibStub("AceGUI-3.0") --[[-----------------------------------------------------------------------------
ColorPicker Widget
-- WoW APIs -------------------------------------------------------------------------------]]
local CreateFrame, UIParent = CreateFrame, UIParent local Type, Version = "ColorPicker", 28
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
-- List them here for Mikk's FindGlobals script
-- GLOBALS: ShowUIPanel, HideUIPanel, ColorPickerFrame, OpacitySliderFrame -- Lua APIs
local pairs = pairs
--------------------------
-- ColorPicker -- -- WoW APIs
-------------------------- local CreateFrame, UIParent = CreateFrame, UIParent
do
local Type = "ColorPicker" -- Unfortunately we have no way to realistically detect if a client uses inverted alpha
local Version = 11 -- as no API will tell you. Wrath uses the old colorpicker, era uses the new one, both are inverted
local INVERTED_ALPHA = (WOW_PROJECT_ID ~= WOW_PROJECT_MAINLINE)
local function OnAcquire(self)
self.HasAlpha = false --[[-----------------------------------------------------------------------------
self:SetColor(0,0,0,1) Support functions
self:SetHeight(24) -------------------------------------------------------------------------------]]
self:SetWidth(200) local function ColorCallback(self, r, g, b, a, isAlpha)
end if INVERTED_ALPHA and a then
a = 1 - a
local function SetLabel(self, text) end
self.text:SetText(text) if not self.HasAlpha then
end a = 1
end
local function SetColor(self,r,g,b,a) -- no change, skip update
self.r = r if r == self.r and g == self.g and b == self.b and a == self.a then
self.g = g return
self.b = b end
self.a = a or 1 self:SetColor(r, g, b, a)
self.colorSwatch:SetVertexColor(r,g,b,a) if ColorPickerFrame:IsVisible() then
end --colorpicker is still open
self:Fire("OnValueChanged", r, g, b, a)
local function Control_OnEnter(this) else
this.obj:Fire("OnEnter") --colorpicker is closed, color callback is first, ignore it,
end --alpha callback is the final call after it closes so confirm now
if isAlpha then
local function Control_OnLeave(this) self:Fire("OnValueConfirmed", r, g, b, a)
this.obj:Fire("OnLeave") end
end end
end
local function SetHasAlpha(self, HasAlpha)
self.HasAlpha = HasAlpha --[[-----------------------------------------------------------------------------
end Scripts
-------------------------------------------------------------------------------]]
local function ColorCallback(self,r,g,b,a,isAlpha) local function Control_OnEnter(frame)
if not self.HasAlpha then frame.obj:Fire("OnEnter")
a = 1 end
end
self:SetColor(r,g,b,a) local function Control_OnLeave(frame)
if ColorPickerFrame:IsVisible() then frame.obj:Fire("OnLeave")
--colorpicker is still open end
self:Fire("OnValueChanged",r,g,b,a) local function ColorSwatch_OnClick(frame)
else ColorPickerFrame:Hide()
--colorpicker is closed, color callback is first, ignore it, local self = frame.obj
--alpha callback is the final call after it closes so confirm now if not self.disabled then
if isAlpha then ColorPickerFrame:SetFrameStrata("FULLSCREEN_DIALOG")
self:Fire("OnValueConfirmed",r,g,b,a) ColorPickerFrame:SetFrameLevel(frame:GetFrameLevel() + 10)
end ColorPickerFrame:SetClampedToScreen(true)
end
end if ColorPickerFrame.SetupColorPickerAndShow then -- 10.2.5 color picker overhaul
local r2, g2, b2, a2 = self.r, self.g, self.b, (self.a or 1)
local function ColorSwatch_OnClick(this) if INVERTED_ALPHA then
HideUIPanel(ColorPickerFrame) a2 = 1 - a2
local self = this.obj end
if not self.disabled then
ColorPickerFrame:SetFrameStrata("FULLSCREEN_DIALOG") local info = {
swatchFunc = function()
ColorPickerFrame.func = function() local r, g, b = ColorPickerFrame:GetColorRGB()
local r,g,b = ColorPickerFrame:GetColorRGB() local a = ColorPickerFrame:GetColorAlpha()
local a = 1 - OpacitySliderFrame:GetValue() ColorCallback(self, r, g, b, a)
ColorCallback(self,r,g,b,a) end,
end
hasOpacity = self.HasAlpha,
ColorPickerFrame.hasOpacity = self.HasAlpha opacityFunc = function()
ColorPickerFrame.opacityFunc = function() local r, g, b = ColorPickerFrame:GetColorRGB()
local r,g,b = ColorPickerFrame:GetColorRGB() local a = ColorPickerFrame:GetColorAlpha()
local a = 1 - OpacitySliderFrame:GetValue() ColorCallback(self, r, g, b, a, true)
ColorCallback(self,r,g,b,a,true) end,
end opacity = a2,
local r, g, b, a = self.r, self.g, self.b, self.a
if self.HasAlpha then cancelFunc = function()
ColorPickerFrame.opacity = 1 - (a or 0) ColorCallback(self, r2, g2, b2, a2, true)
end end,
ColorPickerFrame:SetColorRGB(r, g, b)
r = r2,
ColorPickerFrame.cancelFunc = function() g = g2,
ColorCallback(self,r,g,b,a,true) b = b2,
end }
ShowUIPanel(ColorPickerFrame)
end ColorPickerFrame:SetupColorPickerAndShow(info)
AceGUI:ClearFocus() else
end ColorPickerFrame.func = function()
local r, g, b = ColorPickerFrame:GetColorRGB()
local function OnRelease(self) local a = OpacitySliderFrame:GetValue()
self.frame:ClearAllPoints() ColorCallback(self, r, g, b, a)
self.frame:Hide() end
end
ColorPickerFrame.hasOpacity = self.HasAlpha
local function SetDisabled(self, disabled) ColorPickerFrame.opacityFunc = function()
self.disabled = disabled local r, g, b = ColorPickerFrame:GetColorRGB()
if self.disabled then local a = OpacitySliderFrame:GetValue()
self.frame:Disable() ColorCallback(self, r, g, b, a, true)
self.text:SetTextColor(0.5,0.5,0.5) end
else
self.frame:Enable() local r, g, b, a = self.r, self.g, self.b, 1 - (self.a or 1)
self.text:SetTextColor(1,1,1) if self.HasAlpha then
end ColorPickerFrame.opacity = a
end end
ColorPickerFrame:SetColorRGB(r, g, b)
local function Constructor()
local frame = CreateFrame("Button",nil,UIParent) ColorPickerFrame.cancelFunc = function()
local self = {} ColorCallback(self, r, g, b, a, true)
self.type = Type end
self.OnRelease = OnRelease ColorPickerFrame:Show()
self.OnAcquire = OnAcquire end
end
self.SetLabel = SetLabel AceGUI:ClearFocus()
self.SetColor = SetColor end
self.SetDisabled = SetDisabled
self.SetHasAlpha = SetHasAlpha --[[-----------------------------------------------------------------------------
Methods
self.frame = frame -------------------------------------------------------------------------------]]
frame.obj = self local methods = {
["OnAcquire"] = function(self)
local text = frame:CreateFontString(nil,"OVERLAY","GameFontHighlight") self:SetHeight(24)
self.text = text self:SetWidth(200)
text:SetJustifyH("LEFT") self:SetHasAlpha(false)
text:SetTextColor(1,1,1) self:SetColor(0, 0, 0, 1)
frame:SetHeight(24) self:SetDisabled(nil)
frame:SetWidth(200) self:SetLabel(nil)
text:SetHeight(24) end,
frame:SetScript("OnClick", ColorSwatch_OnClick)
frame:SetScript("OnEnter",Control_OnEnter) -- ["OnRelease"] = nil,
frame:SetScript("OnLeave",Control_OnLeave)
["SetLabel"] = function(self, text)
local colorSwatch = frame:CreateTexture(nil, "OVERLAY") self.text:SetText(text)
self.colorSwatch = colorSwatch end,
colorSwatch:SetWidth(19)
colorSwatch:SetHeight(19) ["SetColor"] = function(self, r, g, b, a)
colorSwatch:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch") self.r = r
local texture = frame:CreateTexture(nil, "BACKGROUND") self.g = g
colorSwatch.texture = texture self.b = b
texture:SetWidth(16) self.a = a or 1
texture:SetHeight(16) self.colorSwatch:SetVertexColor(r, g, b, a)
texture:SetTexture(1,1,1) end,
texture:Show()
["SetHasAlpha"] = function(self, HasAlpha)
local checkers = frame:CreateTexture(nil, "BACKGROUND") self.HasAlpha = HasAlpha
colorSwatch.checkers = checkers end,
checkers:SetTexture("Tileset\\Generic\\Checkers")
checkers:SetDesaturated(true) ["SetDisabled"] = function(self, disabled)
checkers:SetVertexColor(1,1,1,0.75) self.disabled = disabled
checkers:SetTexCoord(.25,0,0.5,.25) if self.disabled then
checkers:SetWidth(14) self.frame:Disable()
checkers:SetHeight(14) self.text:SetTextColor(0.5, 0.5, 0.5)
checkers:Show() else
self.frame:Enable()
local highlight = frame:CreateTexture(nil, "BACKGROUND") self.text:SetTextColor(1, 1, 1)
self.highlight = highlight end
highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight") end
highlight:SetBlendMode("ADD") }
highlight:SetAllPoints(frame)
highlight:Hide() --[[-----------------------------------------------------------------------------
Constructor
texture:SetPoint("CENTER", colorSwatch, "CENTER") -------------------------------------------------------------------------------]]
checkers:SetPoint("CENTER", colorSwatch, "CENTER") local function Constructor()
colorSwatch:SetPoint("LEFT", frame, "LEFT", 0, 0) local frame = CreateFrame("Button", nil, UIParent)
text:SetPoint("LEFT",colorSwatch,"RIGHT",2,0) frame:Hide()
text:SetPoint("RIGHT",frame,"RIGHT")
frame:EnableMouse(true)
AceGUI:RegisterAsWidget(self) frame:SetScript("OnEnter", Control_OnEnter)
return self frame:SetScript("OnLeave", Control_OnLeave)
end frame:SetScript("OnClick", ColorSwatch_OnClick)
AceGUI:RegisterWidgetType(Type,Constructor,Version) local colorSwatch = frame:CreateTexture(nil, "OVERLAY")
end colorSwatch:SetWidth(19)
colorSwatch:SetHeight(19)
colorSwatch:SetTexture(130939) -- Interface\\ChatFrame\\ChatFrameColorSwatch
colorSwatch:SetPoint("LEFT")
local texture = frame:CreateTexture(nil, "BACKGROUND")
colorSwatch.background = texture
texture:SetWidth(16)
texture:SetHeight(16)
texture:SetColorTexture(1, 1, 1)
texture:SetPoint("CENTER", colorSwatch)
texture:Show()
local checkers = frame:CreateTexture(nil, "BACKGROUND")
colorSwatch.checkers = checkers
checkers:SetWidth(14)
checkers:SetHeight(14)
checkers:SetTexture(188523) -- Tileset\\Generic\\Checkers
checkers:SetTexCoord(.25, 0, 0.5, .25)
checkers:SetDesaturated(true)
checkers:SetVertexColor(1, 1, 1, 0.75)
checkers:SetPoint("CENTER", colorSwatch)
checkers:Show()
local text = frame:CreateFontString(nil,"OVERLAY","GameFontHighlight")
text:SetHeight(24)
text:SetJustifyH("LEFT")
text:SetTextColor(1, 1, 1)
text:SetPoint("LEFT", colorSwatch, "RIGHT", 2, 0)
text:SetPoint("RIGHT")
--local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
--highlight:SetTexture(136810) -- Interface\\QuestFrame\\UI-QuestTitleHighlight
--highlight:SetBlendMode("ADD")
--highlight:SetAllPoints(frame)
local widget = {
colorSwatch = colorSwatch,
text = text,
frame = frame,
type = Type
}
for method, func in pairs(methods) do
widget[method] = func
end
return AceGUI:RegisterAsWidget(widget)
end
AceGUI:RegisterWidgetType(Type, Constructor, Version)
@@ -1,459 +1,471 @@
--[[ $Id: AceGUIWidget-DropDown-Items.lua 877 2009-11-02 15:56:50Z nevcairiel $ ]]-- --[[ $Id$ ]]--
local AceGUI = LibStub("AceGUI-3.0") local AceGUI = LibStub("AceGUI-3.0")
-- Lua APIs -- Lua APIs
local select, assert = select, assert local select, assert = select, assert
-- WoW APIs -- WoW APIs
local CreateFrame = CreateFrame local PlaySound = PlaySound
local CreateFrame = CreateFrame
local function fixlevels(parent,...)
local i = 1 local function fixlevels(parent,...)
local child = select(i, ...) local i = 1
while child do local child = select(i, ...)
child:SetFrameLevel(parent:GetFrameLevel()+1) while child do
fixlevels(child, child:GetChildren()) child:SetFrameLevel(parent:GetFrameLevel()+1)
i = i + 1 fixlevels(child, child:GetChildren())
child = select(i, ...) i = i + 1
end child = select(i, ...)
end end
end
local function fixstrata(strata, parent, ...)
local i = 1 local function fixstrata(strata, parent, ...)
local child = select(i, ...) local i = 1
parent:SetFrameStrata(strata) local child = select(i, ...)
while child do parent:SetFrameStrata(strata)
fixstrata(strata, child, child:GetChildren()) while child do
i = i + 1 fixstrata(strata, child, child:GetChildren())
child = select(i, ...) i = i + 1
end child = select(i, ...)
end end
end
-- ItemBase is the base "class" for all dropdown items.
-- Each item has to use ItemBase.Create(widgetType) to -- ItemBase is the base "class" for all dropdown items.
-- create an initial 'self' value. -- Each item has to use ItemBase.Create(widgetType) to
-- ItemBase will add common functions and ui event handlers. -- create an initial 'self' value.
-- Be sure to keep basic usage when you override functions. -- ItemBase will add common functions and ui event handlers.
-- Be sure to keep basic usage when you override functions.
local ItemBase = {
-- NOTE: The ItemBase version is added to each item's version number local ItemBase = {
-- to ensure proper updates on ItemBase changes. -- NOTE: The ItemBase version is added to each item's version number
-- Use at least 1000er steps. -- to ensure proper updates on ItemBase changes.
version = 1000, -- Use at least 1000er steps.
counter = 0, version = 2000,
} counter = 0,
}
function ItemBase.Frame_OnEnter(this)
local self = this.obj function ItemBase.Frame_OnEnter(this)
local self = this.obj
if self.useHighlight then
self.highlight:Show() if self.useHighlight then
end self.highlight:Show()
self:Fire("OnEnter") end
self:Fire("OnEnter")
if self.specialOnEnter then
self.specialOnEnter(self) if self.specialOnEnter then
end self.specialOnEnter(self)
end end
end
function ItemBase.Frame_OnLeave(this)
local self = this.obj function ItemBase.Frame_OnLeave(this)
local self = this.obj
self.highlight:Hide()
self:Fire("OnLeave") self.highlight:Hide()
self:Fire("OnLeave")
if self.specialOnLeave then
self.specialOnLeave(self) if self.specialOnLeave then
end self.specialOnLeave(self)
end end
end
-- exported, AceGUI callback
function ItemBase.OnAcquire(self) -- exported, AceGUI callback
self.frame:SetToplevel(true) function ItemBase.OnAcquire(self)
self.frame:SetFrameStrata("FULLSCREEN_DIALOG") self.frame:SetToplevel(true)
end self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
end
-- exported, AceGUI callback
function ItemBase.OnRelease(self) -- exported, AceGUI callback
self:SetDisabled(false) function ItemBase.OnRelease(self)
self.pullout = nil self:SetDisabled(false)
self.frame:SetParent(nil) self.pullout = nil
self.frame:ClearAllPoints() self.frame:SetParent(nil)
self.frame:Hide() self.frame:ClearAllPoints()
end self.frame:Hide()
end
-- exported
-- NOTE: this is called by a Dropdown-Pullout. -- exported
-- Do not call this method directly -- NOTE: this is called by a Dropdown-Pullout.
function ItemBase.SetPullout(self, pullout) -- Do not call this method directly
self.pullout = pullout function ItemBase.SetPullout(self, pullout)
self.pullout = pullout
self.frame:SetParent(nil)
self.frame:SetParent(pullout.itemFrame) self.frame:SetParent(nil)
self.parent = pullout.itemFrame self.frame:SetParent(pullout.itemFrame)
fixlevels(pullout.itemFrame, pullout.itemFrame:GetChildren()) self.parent = pullout.itemFrame
end fixlevels(pullout.itemFrame, pullout.itemFrame:GetChildren())
end
-- exported
function ItemBase.SetText(self, text) -- exported
self.text:SetText(text or "") function ItemBase.SetText(self, text)
end self.text:SetText(text or "")
end
-- exported
function ItemBase.GetText(self) -- exported
return self.text:GetText() function ItemBase.GetText(self)
end return self.text:GetText()
end
-- exported
function ItemBase.SetPoint(self, ...) -- exported
self.frame:SetPoint(...) function ItemBase.SetPoint(self, ...)
end self.frame:SetPoint(...)
end
-- exported
function ItemBase.Show(self) -- exported
self.frame:Show() function ItemBase.Show(self)
end self.frame:Show()
end
-- exported
function ItemBase.Hide(self) -- exported
self.frame:Hide() function ItemBase.Hide(self)
end self.frame:Hide()
end
-- exported
function ItemBase.SetDisabled(self, disabled) -- exported
self.disabled = disabled function ItemBase.SetDisabled(self, disabled)
if disabled then self.disabled = disabled
self.useHighlight = false if disabled then
self.text:SetTextColor(.5, .5, .5) self.useHighlight = false
else self.text:SetTextColor(.5, .5, .5)
self.useHighlight = true else
self.text:SetTextColor(1, 1, 1) self.useHighlight = true
end self.text:SetTextColor(1, 1, 1)
end end
end
-- exported
-- NOTE: this is called by a Dropdown-Pullout. -- exported
-- Do not call this method directly -- NOTE: this is called by a Dropdown-Pullout.
function ItemBase.SetOnLeave(self, func) -- Do not call this method directly
self.specialOnLeave = func function ItemBase.SetOnLeave(self, func)
end self.specialOnLeave = func
end
-- exported
-- NOTE: this is called by a Dropdown-Pullout. -- exported
-- Do not call this method directly -- NOTE: this is called by a Dropdown-Pullout.
function ItemBase.SetOnEnter(self, func) -- Do not call this method directly
self.specialOnEnter = func function ItemBase.SetOnEnter(self, func)
end self.specialOnEnter = func
end
function ItemBase.Create(type)
-- NOTE: Most of the following code is copied from AceGUI-3.0/Dropdown widget function ItemBase.Create(type)
local count = AceGUI:GetNextWidgetNum(type) -- NOTE: Most of the following code is copied from AceGUI-3.0/Dropdown widget
local frame = CreateFrame("Button", "AceGUI30DropDownItem"..count) local count = AceGUI:GetNextWidgetNum(type)
local self = {} local frame = CreateFrame("Button", "AceGUI30DropDownItem"..count)
self.frame = frame local self = {}
frame.obj = self self.frame = frame
self.type = type frame.obj = self
self.type = type
self.useHighlight = true
self.useHighlight = true
frame:SetHeight(17)
frame:SetFrameStrata("FULLSCREEN_DIALOG") frame:SetHeight(17)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
local text = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
text:SetTextColor(1,1,1) local text = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
text:SetJustifyH("LEFT") text:SetTextColor(1,1,1)
text:SetPoint("TOPLEFT",frame,"TOPLEFT",18,0) text:SetJustifyH("LEFT")
text:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-8,0) text:SetPoint("TOPLEFT",frame,"TOPLEFT",18,0)
self.text = text text:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-8,0)
self.text = text
local highlight = frame:CreateTexture(nil, "OVERLAY")
highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight") local highlight = frame:CreateTexture(nil, "OVERLAY")
highlight:SetBlendMode("ADD") highlight:SetTexture(136810) -- Interface\\QuestFrame\\UI-QuestTitleHighlight
highlight:SetHeight(14) highlight:SetBlendMode("ADD")
highlight:ClearAllPoints() highlight:SetHeight(14)
highlight:SetPoint("RIGHT",frame,"RIGHT",-3,0) highlight:ClearAllPoints()
highlight:SetPoint("LEFT",frame,"LEFT",5,0) highlight:SetPoint("RIGHT",frame,"RIGHT",-3,0)
highlight:Hide() highlight:SetPoint("LEFT",frame,"LEFT",5,0)
self.highlight = highlight highlight:Hide()
self.highlight = highlight
local check = frame:CreateTexture("OVERLAY")
check:SetWidth(16) local check = frame:CreateTexture(nil, "OVERLAY")
check:SetHeight(16) check:SetWidth(16)
check:SetPoint("LEFT",frame,"LEFT",3,-1) check:SetHeight(16)
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check") check:SetPoint("LEFT",frame,"LEFT",3,-1)
check:Hide() check:SetTexture(130751) -- Interface\\Buttons\\UI-CheckBox-Check
self.check = check check:Hide()
self.check = check
local sub = frame:CreateTexture("OVERLAY")
sub:SetWidth(16) local sub = frame:CreateTexture(nil, "OVERLAY")
sub:SetHeight(16) sub:SetWidth(16)
sub:SetPoint("RIGHT",frame,"RIGHT",-3,-1) sub:SetHeight(16)
sub:SetTexture("Interface\\ChatFrame\\ChatFrameExpandArrow") sub:SetPoint("RIGHT",frame,"RIGHT",-3,-1)
sub:Hide() sub:SetTexture(130940) -- Interface\\ChatFrame\\ChatFrameExpandArrow
self.sub = sub sub:Hide()
self.sub = sub
frame:SetScript("OnEnter", ItemBase.Frame_OnEnter)
frame:SetScript("OnLeave", ItemBase.Frame_OnLeave) frame:SetScript("OnEnter", ItemBase.Frame_OnEnter)
frame:SetScript("OnLeave", ItemBase.Frame_OnLeave)
self.OnAcquire = ItemBase.OnAcquire
self.OnRelease = ItemBase.OnRelease self.OnAcquire = ItemBase.OnAcquire
self.OnRelease = ItemBase.OnRelease
self.SetPullout = ItemBase.SetPullout
self.GetText = ItemBase.GetText self.SetPullout = ItemBase.SetPullout
self.SetText = ItemBase.SetText self.GetText = ItemBase.GetText
self.SetDisabled = ItemBase.SetDisabled self.SetText = ItemBase.SetText
self.SetDisabled = ItemBase.SetDisabled
self.SetPoint = ItemBase.SetPoint
self.Show = ItemBase.Show self.SetPoint = ItemBase.SetPoint
self.Hide = ItemBase.Hide self.Show = ItemBase.Show
self.Hide = ItemBase.Hide
self.SetOnLeave = ItemBase.SetOnLeave
self.SetOnEnter = ItemBase.SetOnEnter self.SetOnLeave = ItemBase.SetOnLeave
self.SetOnEnter = ItemBase.SetOnEnter
return self
end return self
end
--[[
Template for items: -- Register a dummy LibStub library to retrieve the ItemBase, so other addons can use it.
local IBLib = LibStub:NewLibrary("AceGUI-3.0-DropDown-ItemBase", ItemBase.version)
-- Item: if IBLib then
-- IBLib.GetItemBase = function() return ItemBase end
do end
local widgetType = "Dropdown-Item-"
local widgetVersion = 1 --[[
Template for items:
local function Constructor()
local self = ItemBase.Create(widgetType) -- Item:
--
AceGUI:RegisterAsWidget(self) do
return self local widgetType = "Dropdown-Item-"
end local widgetVersion = 1
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version) local function Constructor()
end local self = ItemBase.Create(widgetType)
--]]
AceGUI:RegisterAsWidget(self)
-- Item: Header return self
-- A single text entry. end
-- Special: Different text color and no highlight
do AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
local widgetType = "Dropdown-Item-Header" end
local widgetVersion = 1 --]]
local function OnEnter(this) -- Item: Header
local self = this.obj -- A single text entry.
self:Fire("OnEnter") -- Special: Different text color and no highlight
do
if self.specialOnEnter then local widgetType = "Dropdown-Item-Header"
self.specialOnEnter(self) local widgetVersion = 1
end
end local function OnEnter(this)
local self = this.obj
local function OnLeave(this) self:Fire("OnEnter")
local self = this.obj
self:Fire("OnLeave") if self.specialOnEnter then
self.specialOnEnter(self)
if self.specialOnLeave then end
self.specialOnLeave(self) end
end
end local function OnLeave(this)
local self = this.obj
-- exported, override self:Fire("OnLeave")
local function SetDisabled(self, disabled)
ItemBase.SetDisabled(self, disabled) if self.specialOnLeave then
if not disabled then self.specialOnLeave(self)
self.text:SetTextColor(1, 1, 0) end
end end
end
-- exported, override
local function Constructor() local function SetDisabled(self, disabled)
local self = ItemBase.Create(widgetType) ItemBase.SetDisabled(self, disabled)
if not disabled then
self.SetDisabled = SetDisabled self.text:SetTextColor(1, 1, 0)
end
self.frame:SetScript("OnEnter", OnEnter) end
self.frame:SetScript("OnLeave", OnLeave)
local function Constructor()
self.text:SetTextColor(1, 1, 0) local self = ItemBase.Create(widgetType)
AceGUI:RegisterAsWidget(self) self.SetDisabled = SetDisabled
return self
end self.frame:SetScript("OnEnter", OnEnter)
self.frame:SetScript("OnLeave", OnLeave)
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end self.text:SetTextColor(1, 1, 0)
-- Item: Execute AceGUI:RegisterAsWidget(self)
-- A simple button return self
do end
local widgetType = "Dropdown-Item-Execute"
local widgetVersion = 1 AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end
local function Frame_OnClick(this, button)
local self = this.obj -- Item: Execute
if self.disabled then return end -- A simple button
self:Fire("OnClick") do
if self.pullout then local widgetType = "Dropdown-Item-Execute"
self.pullout:Close() local widgetVersion = 1
end
end local function Frame_OnClick(this, button)
local self = this.obj
local function Constructor() if self.disabled then return end
local self = ItemBase.Create(widgetType) self:Fire("OnClick")
if self.pullout then
self.frame:SetScript("OnClick", Frame_OnClick) self.pullout:Close()
end
AceGUI:RegisterAsWidget(self) end
return self
end local function Constructor()
local self = ItemBase.Create(widgetType)
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end self.frame:SetScript("OnClick", Frame_OnClick)
-- Item: Toggle AceGUI:RegisterAsWidget(self)
-- Some sort of checkbox for dropdown menus. return self
-- Does not close the pullout on click. end
do
local widgetType = "Dropdown-Item-Toggle" AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
local widgetVersion = 2 end
local function UpdateToggle(self) -- Item: Toggle
if self.value then -- Some sort of checkbox for dropdown menus.
self.check:Show() -- Does not close the pullout on click.
else do
self.check:Hide() local widgetType = "Dropdown-Item-Toggle"
end local widgetVersion = 4
end
local function UpdateToggle(self)
local function OnRelease(self) if self.value then
ItemBase.OnRelease(self) self.check:Show()
self:SetValue(nil) else
end self.check:Hide()
end
local function Frame_OnClick(this, button) end
local self = this.obj
if self.disabled then return end local function OnRelease(self)
self.value = not self.value ItemBase.OnRelease(self)
UpdateToggle(self) self:SetValue(nil)
self:Fire("OnValueChanged", self.value) end
end
local function Frame_OnClick(this, button)
-- exported local self = this.obj
local function SetValue(self, value) if self.disabled then return end
self.value = value self.value = not self.value
UpdateToggle(self) if self.value then
end PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
else
-- exported PlaySound(857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF
local function GetValue(self) end
return self.value UpdateToggle(self)
end self:Fire("OnValueChanged", self.value)
end
local function Constructor()
local self = ItemBase.Create(widgetType) -- exported
local function SetValue(self, value)
self.frame:SetScript("OnClick", Frame_OnClick) self.value = value
UpdateToggle(self)
self.SetValue = SetValue end
self.GetValue = GetValue
self.OnRelease = OnRelease -- exported
local function GetValue(self)
AceGUI:RegisterAsWidget(self) return self.value
return self end
end
local function Constructor()
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version) local self = ItemBase.Create(widgetType)
end
self.frame:SetScript("OnClick", Frame_OnClick)
-- Item: Menu
-- Shows a submenu on mouse over self.SetValue = SetValue
-- Does not close the pullout on click self.GetValue = GetValue
do self.OnRelease = OnRelease
local widgetType = "Dropdown-Item-Menu"
local widgetVersion = 2 AceGUI:RegisterAsWidget(self)
return self
local function OnEnter(this) end
local self = this.obj
self:Fire("OnEnter") AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end
if self.specialOnEnter then
self.specialOnEnter(self) -- Item: Menu
end -- Shows a submenu on mouse over
-- Does not close the pullout on click
self.highlight:Show() do
local widgetType = "Dropdown-Item-Menu"
if not self.disabled and self.submenu then local widgetVersion = 2
self.submenu:Open("TOPLEFT", self.frame, "TOPRIGHT", self.pullout:GetRightBorderWidth(), 0, self.frame:GetFrameLevel() + 100)
end local function OnEnter(this)
end local self = this.obj
self:Fire("OnEnter")
local function OnHide(this)
local self = this.obj if self.specialOnEnter then
if self.submenu then self.specialOnEnter(self)
self.submenu:Close() end
end
end self.highlight:Show()
-- exported if not self.disabled and self.submenu then
local function SetMenu(self, menu) self.submenu:Open("TOPLEFT", self.frame, "TOPRIGHT", self.pullout:GetRightBorderWidth(), 0, self.frame:GetFrameLevel() + 100)
assert(menu.type == "Dropdown-Pullout") end
self.submenu = menu end
end
local function OnHide(this)
-- exported local self = this.obj
local function CloseMenu(self) if self.submenu then
self.submenu:Close() self.submenu:Close()
end end
end
local function Constructor()
local self = ItemBase.Create(widgetType) -- exported
local function SetMenu(self, menu)
self.sub:Show() assert(menu.type == "Dropdown-Pullout")
self.submenu = menu
self.frame:SetScript("OnEnter", OnEnter) end
self.frame:SetScript("OnHide", OnHide)
-- exported
self.SetMenu = SetMenu local function CloseMenu(self)
self.CloseMenu = CloseMenu self.submenu:Close()
end
AceGUI:RegisterAsWidget(self)
return self local function Constructor()
end local self = ItemBase.Create(widgetType)
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version) self.sub:Show()
end
self.frame:SetScript("OnEnter", OnEnter)
-- Item: Separator self.frame:SetScript("OnHide", OnHide)
-- A single line to separate items
do self.SetMenu = SetMenu
local widgetType = "Dropdown-Item-Separator" self.CloseMenu = CloseMenu
local widgetVersion = 1
AceGUI:RegisterAsWidget(self)
-- exported, override return self
local function SetDisabled(self, disabled) end
ItemBase.SetDisabled(self, disabled)
self.useHighlight = false AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end end
local function Constructor() -- Item: Separator
local self = ItemBase.Create(widgetType) -- A single line to separate items
do
self.SetDisabled = SetDisabled local widgetType = "Dropdown-Item-Separator"
local widgetVersion = 2
local line = self.frame:CreateTexture(nil, "OVERLAY")
line:SetHeight(1) -- exported, override
line:SetTexture(.5, .5, .5) local function SetDisabled(self, disabled)
line:SetPoint("LEFT", self.frame, "LEFT", 10, 0) ItemBase.SetDisabled(self, disabled)
line:SetPoint("RIGHT", self.frame, "RIGHT", -10, 0) self.useHighlight = false
end
self.text:Hide()
local function Constructor()
self.useHighlight = false local self = ItemBase.Create(widgetType)
AceGUI:RegisterAsWidget(self) self.SetDisabled = SetDisabled
return self
end local line = self.frame:CreateTexture(nil, "OVERLAY")
line:SetHeight(1)
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version) line:SetColorTexture(.5, .5, .5)
end line:SetPoint("LEFT", self.frame, "LEFT", 10, 0)
line:SetPoint("RIGHT", self.frame, "RIGHT", -10, 0)
self.text:Hide()
self.useHighlight = false
AceGUI:RegisterAsWidget(self)
return self
end
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end
File diff suppressed because it is too large Load Diff
@@ -1,178 +0,0 @@
local AceGUI = LibStub("AceGUI-3.0")
-- Lua APIs
local assert, pairs, type = assert, pairs, type
-- WoW APIs
local CreateFrame = CreateFrame
--[[
Selection Group controls all have an interface to select a group for thier contents
None of them will auto size to thier contents, and should usually be used with a scrollframe
unless you know that the controls will fit inside
]]
--------------------------
-- Dropdown Group --
--------------------------
--[[
Events :
OnGroupSelected
]]
do
local Type = "DropdownGroup"
local Version = 13
local function OnAcquire(self)
self.dropdown:SetText("")
self:SetDropdownWidth(200)
self:SetTitle("")
end
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
self.dropdown.list = nil
self.status = nil
for k in pairs(self.localstatus) do
self.localstatus[k] = nil
end
end
local PaneBackdrop = {
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 16,
insets = { left = 3, right = 3, top = 5, bottom = 3 }
}
local function SetTitle(self,title)
self.titletext:SetText(title)
self.dropdown.frame:ClearAllPoints()
if title and title ~= "" then
self.dropdown.frame:SetPoint("TOPRIGHT", self.frame, "TOPRIGHT", -2, 0)
else
self.dropdown.frame:SetPoint("TOPLEFT", self.frame, "TOPLEFT", -1, 0)
end
end
local function SelectedGroup(self,event,value)
local group = self.parentgroup
local status = group.status or group.localstatus
status.selected = value
self.parentgroup:Fire("OnGroupSelected", value)
end
local function SetGroupList(self,list)
self.dropdown:SetList(list)
end
-- called to set an external table to store status in
local function SetStatusTable(self, status)
assert(type(status) == "table")
self.status = status
end
local function SetGroup(self,group)
self.dropdown:SetValue(group)
local status = self.status or self.localstatus
status.selected = group
self:Fire("OnGroupSelected", group)
end
local function OnWidthSet(self, width)
local content = self.content
local contentwidth = width - 26
if contentwidth < 0 then
contentwidth = 0
end
content:SetWidth(contentwidth)
content.width = contentwidth
end
local function OnHeightSet(self, height)
local content = self.content
local contentheight = height - 63
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end
local function LayoutFinished(self, width, height)
self:SetHeight((height or 0) + 63)
end
local function SetDropdownWidth(self, width)
self.dropdown:SetWidth(width)
end
local function Constructor()
local frame = CreateFrame("Frame")
local self = {}
self.type = Type
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.SetTitle = SetTitle
self.SetGroupList = SetGroupList
self.SetGroup = SetGroup
self.SetStatusTable = SetStatusTable
self.SetDropdownWidth = SetDropdownWidth
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
self.LayoutFinished = LayoutFinished
self.localstatus = {}
self.frame = frame
frame.obj = self
frame:SetHeight(100)
frame:SetWidth(100)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
local titletext = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
titletext:SetPoint("TOPLEFT", frame, "TOPLEFT", 4, -5)
titletext:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -4, -5)
titletext:SetJustifyH("LEFT")
titletext:SetHeight(18)
self.titletext = titletext
local dropdown = AceGUI:Create("Dropdown")
self.dropdown = dropdown
dropdown.frame:SetParent(frame)
dropdown.frame:SetFrameLevel(dropdown.frame:GetFrameLevel() + 2)
dropdown.parentgroup = self
dropdown:SetCallback("OnValueChanged",SelectedGroup)
dropdown.frame:SetPoint("TOPLEFT",frame,"TOPLEFT", -1, 0)
dropdown.frame:Show()
dropdown:SetLabel("")
local border = CreateFrame("Frame",nil,frame)
self.border = border
border:SetPoint("TOPLEFT",frame,"TOPLEFT",0,-26)
border:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,3)
border:SetBackdrop(PaneBackdrop)
border:SetBackdropColor(0.1,0.1,0.1,0.5)
border:SetBackdropBorderColor(0.4,0.4,0.4)
--Container Support
local content = CreateFrame("Frame",nil,border)
self.content = content
content.obj = self
content:SetPoint("TOPLEFT",border,"TOPLEFT",10,-10)
content:SetPoint("BOTTOMRIGHT",border,"BOTTOMRIGHT",-10,10)
AceGUI:RegisterAsContainer(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
+267 -233
View File
@@ -1,233 +1,267 @@
local AceGUI = LibStub("AceGUI-3.0") --[[-----------------------------------------------------------------------------
EditBox Widget
-- Lua APIs -------------------------------------------------------------------------------]]
local tostring = tostring local Type, Version = "EditBox", 29
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
-- WoW APIs if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
local GetCursorInfo, ClearCursor, GetSpellName = GetCursorInfo, ClearCursor, GetSpellName
local CreateFrame, UIParent = CreateFrame, UIParent -- Lua APIs
local _G = _G local tostring, pairs = tostring, pairs
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded -- WoW APIs
-- List them here for Mikk's FindGlobals script local PlaySound = PlaySound
-- GLOBALS: AceGUIEditBoxInsertLink, ChatFontNormal, OKAY local GetCursorInfo, ClearCursor = GetCursorInfo, ClearCursor
local CreateFrame, UIParent = CreateFrame, UIParent
local Type = "EditBox" local _G = _G
local Version = 13
--[[-----------------------------------------------------------------------------
if not AceGUIEditBoxInsertLink then Support functions
-- upgradeable hook -------------------------------------------------------------------------------]]
hooksecurefunc("ChatEdit_InsertLink", function(...) return _G.AceGUIEditBoxInsertLink(...) end) if not AceGUIEditBoxInsertLink then
end -- upgradeable hook
if ChatFrameUtil and ChatFrameUtil.InsertLink then
function _G.AceGUIEditBoxInsertLink(text) hooksecurefunc(ChatFrameUtil, "InsertLink", function(...) return _G.AceGUIEditBoxInsertLink(...) end)
for i = 1, AceGUI:GetNextWidgetNum(Type)-1 do elseif ChatEdit_InsertLink then
local editbox = _G["AceGUI-3.0EditBox"..i] hooksecurefunc("ChatEdit_InsertLink", function(...) return _G.AceGUIEditBoxInsertLink(...) end)
if editbox and editbox:IsVisible() and editbox:HasFocus() then end
editbox:Insert(text) end
return true
end function _G.AceGUIEditBoxInsertLink(text)
end for i = 1, AceGUI:GetWidgetCount(Type) do
end local editbox = _G["AceGUI-3.0EditBox"..i]
if editbox and editbox:IsVisible() and editbox:HasFocus() then
editbox:Insert(text)
-------------------------- return true
-- Edit box -- end
-------------------------- end
--[[ end
Events :
OnTextChanged local function ShowButton(self)
OnEnterPressed if not self.disablebutton then
self.button:Show()
]] self.editbox:SetTextInsets(0, 20, 3, 3)
do end
local function OnAcquire(self) end
self:SetHeight(26)
self:SetWidth(200) local function HideButton(self)
self:SetDisabled(false) self.button:Hide()
self:SetLabel() self.editbox:SetTextInsets(0, 0, 3, 3)
self.showbutton = true end
end
--[[-----------------------------------------------------------------------------
local function OnRelease(self) Scripts
self.frame:ClearAllPoints() -------------------------------------------------------------------------------]]
self.frame:Hide() local function Control_OnEnter(frame)
self:SetDisabled(false) frame.obj:Fire("OnEnter")
self:SetText() end
end
local function Control_OnLeave(frame)
local function Control_OnEnter(this) frame.obj:Fire("OnLeave")
this.obj:Fire("OnEnter") end
end
local function Frame_OnShowFocus(frame)
local function Control_OnLeave(this) frame.obj.editbox:SetFocus()
this.obj:Fire("OnLeave") frame:SetScript("OnShow", nil)
end end
local function EditBox_OnEscapePressed(this) local function EditBox_OnEscapePressed(frame)
this:ClearFocus() AceGUI:ClearFocus()
end end
local function ShowButton(self) local function EditBox_OnEnterPressed(frame)
if self.showbutton then local self = frame.obj
self.button:Show() local value = frame:GetText()
self.editbox:SetTextInsets(0,20,3,3) local cancel = self:Fire("OnEnterPressed", value)
end if not cancel then
end PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
HideButton(self)
local function HideButton(self) end
self.button:Hide() end
self.editbox:SetTextInsets(0,0,3,3)
end local function EditBox_OnReceiveDrag(frame)
local self = frame.obj
local function EditBox_OnEnterPressed(this) local type, id, info, extra = GetCursorInfo()
local self = this.obj local name
local value = this:GetText() if type == "item" then
local cancel = self:Fire("OnEnterPressed",value) name = info
if not cancel then elseif type == "spell" then
HideButton(self) if C_Spell and C_Spell.GetSpellName then
end name = C_Spell.GetSpellName(extra)
end else
name = GetSpellInfo(id, info)
local function Button_OnClick(this) end
local editbox = this.obj.editbox elseif type == "macro" then
editbox:ClearFocus() name = GetMacroInfo(id)
EditBox_OnEnterPressed(editbox) end
end if name then
self:SetText(name)
local function EditBox_OnReceiveDrag(this) self:Fire("OnEnterPressed", name)
local self = this.obj ClearCursor()
local type, id, info = GetCursorInfo() HideButton(self)
if type == "item" then AceGUI:ClearFocus()
self:SetText(info) end
self:Fire("OnEnterPressed",info) end
ClearCursor()
elseif type == "spell" then local function EditBox_OnTextChanged(frame)
local name, rank = GetSpellName(id, info) local self = frame.obj
if rank and rank:match("%d") then local value = frame:GetText()
name = name.."("..rank..")" if tostring(value) ~= tostring(self.lasttext) then
end self:Fire("OnTextChanged", value)
self:SetText(name) self.lasttext = value
self:Fire("OnEnterPressed",name) ShowButton(self)
ClearCursor() end
end end
HideButton(self)
AceGUI:ClearFocus() local function EditBox_OnFocusGained(frame)
end AceGUI:SetFocus(frame.obj)
end
local function EditBox_OnTextChanged(this)
local self = this.obj local function Button_OnClick(frame)
local value = this:GetText() local editbox = frame.obj.editbox
if tostring(value) ~= tostring(self.lasttext) then editbox:ClearFocus()
self:Fire("OnTextChanged",value) EditBox_OnEnterPressed(editbox)
self.lasttext = value end
ShowButton(self)
end --[[-----------------------------------------------------------------------------
end Methods
-------------------------------------------------------------------------------]]
local function SetDisabled(self, disabled) local methods = {
self.disabled = disabled ["OnAcquire"] = function(self)
if disabled then -- height is controlled by SetLabel
self.editbox:EnableMouse(false) self:SetWidth(200)
self.editbox:ClearFocus() self:SetDisabled(false)
self.editbox:SetTextColor(0.5,0.5,0.5) self:SetLabel()
self.label:SetTextColor(0.5,0.5,0.5) self:SetText()
else self:DisableButton(false)
self.editbox:EnableMouse(true) self:SetMaxLetters(0)
self.editbox:SetTextColor(1,1,1) end,
self.label:SetTextColor(1,.82,0)
end ["OnRelease"] = function(self)
end self:ClearFocus()
end,
local function SetText(self, text)
self.lasttext = text or "" ["SetDisabled"] = function(self, disabled)
self.editbox:SetText(text or "") self.disabled = disabled
self.editbox:SetCursorPosition(0) if disabled then
HideButton(self) self.editbox:EnableMouse(false)
end self.editbox:ClearFocus()
self.editbox:SetTextColor(0.5,0.5,0.5)
local function SetLabel(self, text) self.label:SetTextColor(0.5,0.5,0.5)
if text and text ~= "" then else
self.label:SetText(text) self.editbox:EnableMouse(true)
self.label:Show() self.editbox:SetTextColor(1,1,1)
self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,-18) self.label:SetTextColor(1,.82,0)
self:SetHeight(44) end
self.alignoffset = 30 end,
else
self.label:SetText("") ["SetText"] = function(self, text)
self.label:Hide() self.lasttext = text or ""
self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,0) self.editbox:SetText(text or "")
self:SetHeight(26) self.editbox:SetCursorPosition(0)
self.alignoffset = 12 HideButton(self)
end end,
end
["GetText"] = function(self, text)
return self.editbox:GetText()
local function Constructor() end,
local num = AceGUI:GetNextWidgetNum(Type)
local frame = CreateFrame("Frame",nil,UIParent) ["SetLabel"] = function(self, text)
local editbox = CreateFrame("EditBox","AceGUI-3.0EditBox"..num,frame,"InputBoxTemplate") if text and text ~= "" then
self.label:SetText(text)
local self = {} self.label:Show()
self.type = Type self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,-18)
self.num = num self:SetHeight(44)
self.alignoffset = 30
self.OnRelease = OnRelease else
self.OnAcquire = OnAcquire self.label:SetText("")
self.label:Hide()
self.SetDisabled = SetDisabled self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,0)
self.SetText = SetText self:SetHeight(26)
self.SetLabel = SetLabel self.alignoffset = 12
end
self.frame = frame end,
frame.obj = self
self.editbox = editbox ["DisableButton"] = function(self, disabled)
editbox.obj = self self.disablebutton = disabled
if disabled then
self.alignoffset = 30 HideButton(self)
end
frame:SetHeight(44) end,
frame:SetWidth(200)
["SetMaxLetters"] = function (self, num)
editbox:SetScript("OnEnter",Control_OnEnter) self.editbox:SetMaxLetters(num or 0)
editbox:SetScript("OnLeave",Control_OnLeave) end,
editbox:SetAutoFocus(false) ["ClearFocus"] = function(self)
editbox:SetFontObject(ChatFontNormal) self.editbox:ClearFocus()
editbox:SetScript("OnEscapePressed",EditBox_OnEscapePressed) self.frame:SetScript("OnShow", nil)
editbox:SetScript("OnEnterPressed",EditBox_OnEnterPressed) end,
editbox:SetScript("OnTextChanged",EditBox_OnTextChanged)
editbox:SetScript("OnReceiveDrag", EditBox_OnReceiveDrag) ["SetFocus"] = function(self)
editbox:SetScript("OnMouseDown", EditBox_OnReceiveDrag) self.editbox:SetFocus()
if not self.frame:IsShown() then
editbox:SetTextInsets(0,0,3,3) self.frame:SetScript("OnShow", Frame_OnShowFocus)
editbox:SetMaxLetters(256) end
end,
editbox:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",6,0)
editbox:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0) ["HighlightText"] = function(self, from, to)
editbox:SetHeight(19) self.editbox:HighlightText(from, to)
end
local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall") }
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,-2)
label:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,-2) --[[-----------------------------------------------------------------------------
label:SetJustifyH("LEFT") Constructor
label:SetHeight(18) -------------------------------------------------------------------------------]]
self.label = label local function Constructor()
local num = AceGUI:GetNextWidgetNum(Type)
local button = CreateFrame("Button",nil,editbox,"UIPanelButtonTemplate") local frame = CreateFrame("Frame", nil, UIParent)
button:SetWidth(40) frame:Hide()
button:SetHeight(20)
button:SetPoint("RIGHT",editbox,"RIGHT",-2,0) local editbox = CreateFrame("EditBox", "AceGUI-3.0EditBox"..num, frame, "InputBoxTemplate")
button:SetText(OKAY) editbox:SetAutoFocus(false)
button:SetScript("OnClick", Button_OnClick) editbox:SetFontObject(ChatFontNormal)
button:Hide() editbox:SetScript("OnEnter", Control_OnEnter)
editbox:SetScript("OnLeave", Control_OnLeave)
self.button = button editbox:SetScript("OnEscapePressed", EditBox_OnEscapePressed)
button.obj = self editbox:SetScript("OnEnterPressed", EditBox_OnEnterPressed)
editbox:SetScript("OnTextChanged", EditBox_OnTextChanged)
AceGUI:RegisterAsWidget(self) editbox:SetScript("OnReceiveDrag", EditBox_OnReceiveDrag)
return self editbox:SetScript("OnMouseDown", EditBox_OnReceiveDrag)
end editbox:SetScript("OnEditFocusGained", EditBox_OnFocusGained)
editbox:SetTextInsets(0, 0, 3, 3)
AceGUI:RegisterWidgetType(Type,Constructor,Version) editbox:SetMaxLetters(256)
end editbox:SetPoint("BOTTOMLEFT", 6, 0)
editbox:SetPoint("BOTTOMRIGHT")
editbox:SetHeight(19)
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
label:SetPoint("TOPLEFT", 0, -2)
label:SetPoint("TOPRIGHT", 0, -2)
label:SetJustifyH("LEFT")
label:SetHeight(18)
local button = CreateFrame("Button", nil, editbox, "UIPanelButtonTemplate")
button:SetWidth(40)
button:SetHeight(20)
button:SetPoint("RIGHT", -2, 0)
button:SetText(OKAY)
button:SetScript("OnClick", Button_OnClick)
button:Hide()
local widget = {
alignoffset = 30,
editbox = editbox,
label = label,
button = button,
frame = frame,
type = Type
}
for method, func in pairs(methods) do
widget[method] = func
end
editbox.obj, button.obj = widget, widget
return AceGUI:RegisterAsWidget(widget)
end
AceGUI:RegisterWidgetType(Type, Constructor, Version)
@@ -1,305 +0,0 @@
local AceGUI = LibStub("AceGUI-3.0")
-- Lua APIs
local pairs, assert, type = pairs, assert, type
-- WoW APIs
local CreateFrame, UIParent = CreateFrame, UIParent
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: CLOSE
----------------
-- Main Frame --
----------------
--[[
Events :
OnClose
]]
do
local Type = "Frame"
local Version = 9
local FrameBackdrop = {
bgFile="Interface\\DialogFrame\\UI-DialogBox-Background",
edgeFile="Interface\\DialogFrame\\UI-DialogBox-Border",
tile = true, tileSize = 32, edgeSize = 32,
insets = { left = 8, right = 8, top = 8, bottom = 8 }
}
local PaneBackdrop = {
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 16,
insets = { left = 3, right = 3, top = 5, bottom = 3 }
}
local function frameOnClose(this)
this.obj:Fire("OnClose")
end
local function closeOnClick(this)
this.obj:Hide()
end
local function frameOnMouseDown(this)
AceGUI:ClearFocus()
end
local function titleOnMouseDown(this)
this:GetParent():StartMoving()
AceGUI:ClearFocus()
end
local function frameOnMouseUp(this)
local frame = this:GetParent()
frame:StopMovingOrSizing()
local self = frame.obj
local status = self.status or self.localstatus
status.width = frame:GetWidth()
status.height = frame:GetHeight()
status.top = frame:GetTop()
status.left = frame:GetLeft()
end
local function sizerseOnMouseDown(this)
this:GetParent():StartSizing("BOTTOMRIGHT")
AceGUI:ClearFocus()
end
local function sizersOnMouseDown(this)
this:GetParent():StartSizing("BOTTOM")
AceGUI:ClearFocus()
end
local function sizereOnMouseDown(this)
this:GetParent():StartSizing("RIGHT")
AceGUI:ClearFocus()
end
local function SetTitle(self,title)
self.titletext:SetText(title)
end
local function SetStatusText(self,text)
self.statustext:SetText(text)
end
local function Hide(self)
self.frame:Hide()
end
local function Show(self)
self.frame:Show()
end
local function OnAcquire(self)
self.frame:SetParent(UIParent)
self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
self:ApplyStatus()
end
local function OnRelease(self)
self.status = nil
for k in pairs(self.localstatus) do
self.localstatus[k] = nil
end
end
-- called to set an external table to store status in
local function SetStatusTable(self, status)
assert(type(status) == "table")
self.status = status
self:ApplyStatus()
end
local function ApplyStatus(self)
local status = self.status or self.localstatus
local frame = self.frame
self:SetWidth(status.width or 700)
self:SetHeight(status.height or 500)
if status.top and status.left then
frame:SetPoint("TOP",UIParent,"BOTTOM",0,status.top)
frame:SetPoint("LEFT",UIParent,"LEFT",status.left,0)
else
frame:SetPoint("CENTER",UIParent,"CENTER")
end
end
local function OnWidthSet(self, width)
local content = self.content
local contentwidth = width - 34
if contentwidth < 0 then
contentwidth = 0
end
content:SetWidth(contentwidth)
content.width = contentwidth
end
local function OnHeightSet(self, height)
local content = self.content
local contentheight = height - 57
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = "Frame"
self.Hide = Hide
self.Show = Show
self.SetTitle = SetTitle
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.SetStatusText = SetStatusText
self.SetStatusTable = SetStatusTable
self.ApplyStatus = ApplyStatus
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
self.localstatus = {}
self.frame = frame
frame.obj = self
frame:SetWidth(700)
frame:SetHeight(500)
frame:SetPoint("CENTER",UIParent,"CENTER",0,0)
frame:EnableMouse()
frame:SetMovable(true)
frame:SetResizable(true)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
frame:SetScript("OnMouseDown", frameOnMouseDown)
frame:SetBackdrop(FrameBackdrop)
frame:SetBackdropColor(0,0,0,1)
frame:SetScript("OnHide",frameOnClose)
frame:SetMinResize(400,200)
frame:SetToplevel(true)
local closebutton = CreateFrame("Button",nil,frame,"UIPanelButtonTemplate")
closebutton:SetScript("OnClick", closeOnClick)
closebutton:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-27,17)
closebutton:SetHeight(20)
closebutton:SetWidth(100)
closebutton:SetText(CLOSE)
self.closebutton = closebutton
closebutton.obj = self
local statusbg = CreateFrame("Frame",nil,frame)
statusbg:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",15,15)
statusbg:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-132,15)
statusbg:SetHeight(24)
statusbg:SetBackdrop(PaneBackdrop)
statusbg:SetBackdropColor(0.1,0.1,0.1)
statusbg:SetBackdropBorderColor(0.4,0.4,0.4)
self.statusbg = statusbg
local statustext = statusbg:CreateFontString(nil,"OVERLAY","GameFontNormal")
self.statustext = statustext
statustext:SetPoint("TOPLEFT",statusbg,"TOPLEFT",7,-2)
statustext:SetPoint("BOTTOMRIGHT",statusbg,"BOTTOMRIGHT",-7,2)
statustext:SetHeight(20)
statustext:SetJustifyH("LEFT")
statustext:SetText("")
local title = CreateFrame("Frame",nil,frame)
self.title = title
title:EnableMouse()
title:SetScript("OnMouseDown",titleOnMouseDown)
title:SetScript("OnMouseUp", frameOnMouseUp)
local titlebg = frame:CreateTexture(nil,"OVERLAY")
titlebg:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header")
titlebg:SetTexCoord(0.31,0.67,0,0.63)
titlebg:SetPoint("TOP",frame,"TOP",0,12)
titlebg:SetWidth(100)
titlebg:SetHeight(40)
local titlebg_l = frame:CreateTexture(nil,"OVERLAY")
titlebg_l:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header")
titlebg_l:SetTexCoord(0.21,0.31,0,0.63)
titlebg_l:SetPoint("RIGHT",titlebg,"LEFT",0,0)
titlebg_l:SetWidth(30)
titlebg_l:SetHeight(40)
local titlebg_right = frame:CreateTexture(nil,"OVERLAY")
titlebg_right:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header")
titlebg_right:SetTexCoord(0.67,0.77,0,0.63)
titlebg_right:SetPoint("LEFT",titlebg,"RIGHT",0,0)
titlebg_right:SetWidth(30)
titlebg_right:SetHeight(40)
title:SetAllPoints(titlebg)
local titletext = title:CreateFontString(nil,"OVERLAY","GameFontNormal")
titletext:SetPoint("TOP",titlebg,"TOP",0,-14)
self.titletext = titletext
local sizer_se = CreateFrame("Frame",nil,frame)
sizer_se:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
sizer_se:SetWidth(25)
sizer_se:SetHeight(25)
sizer_se:EnableMouse()
sizer_se:SetScript("OnMouseDown",sizerseOnMouseDown)
sizer_se:SetScript("OnMouseUp", frameOnMouseUp)
self.sizer_se = sizer_se
local line1 = sizer_se:CreateTexture(nil, "BACKGROUND")
self.line1 = line1
line1:SetWidth(14)
line1:SetHeight(14)
line1:SetPoint("BOTTOMRIGHT", -8, 8)
line1:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
local x = 0.1 * 14/17
line1:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
local line2 = sizer_se:CreateTexture(nil, "BACKGROUND")
self.line2 = line2
line2:SetWidth(8)
line2:SetHeight(8)
line2:SetPoint("BOTTOMRIGHT", -8, 8)
line2:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
local x = 0.1 * 8/17
line2:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
local sizer_s = CreateFrame("Frame",nil,frame)
sizer_s:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-25,0)
sizer_s:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,0)
sizer_s:SetHeight(25)
sizer_s:EnableMouse()
sizer_s:SetScript("OnMouseDown",sizersOnMouseDown)
sizer_s:SetScript("OnMouseUp", frameOnMouseUp)
self.sizer_s = sizer_s
local sizer_e = CreateFrame("Frame",nil,frame)
sizer_e:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,25)
sizer_e:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
sizer_e:SetWidth(25)
sizer_e:EnableMouse()
sizer_e:SetScript("OnMouseDown",sizereOnMouseDown)
sizer_e:SetScript("OnMouseUp", frameOnMouseUp)
self.sizer_e = sizer_e
--Container Support
local content = CreateFrame("Frame",nil,frame)
self.content = content
content.obj = self
content:SetPoint("TOPLEFT",frame,"TOPLEFT",17,-27)
content:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-17,40)
AceGUI:RegisterAsContainer(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
@@ -1,76 +1,78 @@
local AceGUI = LibStub("AceGUI-3.0") --[[-----------------------------------------------------------------------------
Heading Widget
-- WoW APIs -------------------------------------------------------------------------------]]
local CreateFrame, UIParent = CreateFrame, UIParent local Type, Version = "Heading", 20
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
-------------------------- if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
-- Heading --
-------------------------- -- Lua APIs
do local pairs = pairs
local Type = "Heading"
local Version = 5 -- WoW APIs
local CreateFrame, UIParent = CreateFrame, UIParent
local function OnAcquire(self)
self:SetText("") --[[-----------------------------------------------------------------------------
self:SetFullWidth() Methods
self:SetHeight(18) -------------------------------------------------------------------------------]]
end local methods = {
["OnAcquire"] = function(self)
local function OnRelease(self) self:SetText()
self.frame:ClearAllPoints() self:SetFullWidth()
self.frame:Hide() self:SetHeight(18)
end end,
local function SetText(self, text) -- ["OnRelease"] = nil,
self.label:SetText(text or "")
if (text or "") == "" then ["SetText"] = function(self, text)
self.left:SetPoint("RIGHT",self.frame,"RIGHT",-3,0) self.label:SetText(text or "")
self.right:Hide() if text and text ~= "" then
else self.left:SetPoint("RIGHT", self.label, "LEFT", -5, 0)
self.left:SetPoint("RIGHT",self.label,"LEFT",-5,0) self.right:Show()
self.right:Show() else
end self.left:SetPoint("RIGHT", -3, 0)
end self.right:Hide()
end
local function Constructor() end
local frame = CreateFrame("Frame",nil,UIParent) }
local self = {}
self.type = Type --[[-----------------------------------------------------------------------------
Constructor
self.OnRelease = OnRelease -------------------------------------------------------------------------------]]
self.OnAcquire = OnAcquire local function Constructor()
self.SetText = SetText local frame = CreateFrame("Frame", nil, UIParent)
self.frame = frame frame:Hide()
frame.obj = self
local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontNormal")
frame:SetHeight(18) label:SetPoint("TOP")
label:SetPoint("BOTTOM")
local label = frame:CreateFontString(nil,"BACKGROUND","GameFontNormal") label:SetJustifyH("CENTER")
label:SetPoint("TOP",frame,"TOP",0,0)
label:SetPoint("BOTTOM",frame,"BOTTOM",0,0) local left = frame:CreateTexture(nil, "BACKGROUND")
label:SetJustifyH("CENTER") left:SetHeight(8)
label:SetHeight(18) left:SetPoint("LEFT", 3, 0)
self.label = label left:SetPoint("RIGHT", label, "LEFT", -5, 0)
left:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border
local left = frame:CreateTexture(nil, "BACKGROUND") left:SetTexCoord(0.81, 0.94, 0.5, 1)
self.left = left
left:SetHeight(8) local right = frame:CreateTexture(nil, "BACKGROUND")
left:SetPoint("LEFT",frame,"LEFT",3,0) right:SetHeight(8)
left:SetPoint("RIGHT",label,"LEFT",-5,0) right:SetPoint("RIGHT", -3, 0)
left:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border") right:SetPoint("LEFT", label, "RIGHT", 5, 0)
left:SetTexCoord(0.81, 0.94, 0.5, 1) right:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border
right:SetTexCoord(0.81, 0.94, 0.5, 1)
local right = frame:CreateTexture(nil, "BACKGROUND")
self.right = right local widget = {
right:SetHeight(8) label = label,
right:SetPoint("RIGHT",frame,"RIGHT",-3,0) left = left,
right:SetPoint("LEFT",label,"RIGHT",5,0) right = right,
right:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border") frame = frame,
right:SetTexCoord(0.81, 0.94, 0.5, 1) type = Type
}
AceGUI:RegisterAsWidget(self) for method, func in pairs(methods) do
return self widget[method] = func
end end
AceGUI:RegisterWidgetType(Type,Constructor,Version) return AceGUI:RegisterAsWidget(widget)
end end
AceGUI:RegisterWidgetType(Type, Constructor, Version)
+140 -149
View File
@@ -1,149 +1,140 @@
local AceGUI = LibStub("AceGUI-3.0") --[[-----------------------------------------------------------------------------
Icon Widget
-- Lua APIs -------------------------------------------------------------------------------]]
local select = select local Type, Version = "Icon", 21
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
-- WoW APIs if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
local CreateFrame, UIParent = CreateFrame, UIParent
-- Lua APIs
-------------------------- local select, pairs, print = select, pairs, print
-- Label --
-------------------------- -- WoW APIs
do local CreateFrame, UIParent = CreateFrame, UIParent
local Type = "Icon"
local Version = 11 --[[-----------------------------------------------------------------------------
Scripts
local function OnAcquire(self) -------------------------------------------------------------------------------]]
self:SetHeight(110) local function Control_OnEnter(frame)
self:SetWidth(110) frame.obj:Fire("OnEnter")
self:SetLabel("") end
self:SetImage(nil)
self:SetImageSize(64, 64) local function Control_OnLeave(frame)
end frame.obj:Fire("OnLeave")
end
local function OnRelease(self)
self.frame:ClearAllPoints() local function Button_OnClick(frame, button)
self.frame:Hide() frame.obj:Fire("OnClick", button)
self:SetDisabled(false) AceGUI:ClearFocus()
end end
local function SetLabel(self, text) --[[-----------------------------------------------------------------------------
if text and text ~= "" then Methods
self.label:Show() -------------------------------------------------------------------------------]]
self.label:SetText(text) local methods = {
self.frame:SetHeight(self.image:GetHeight() + 25) ["OnAcquire"] = function(self)
else self:SetHeight(110)
self.label:Hide() self:SetWidth(110)
self.frame:SetHeight(self.image:GetHeight() + 10) self:SetLabel()
end self:SetImage(nil)
end self:SetImageSize(64, 64)
self:SetDisabled(false)
local function SetImage(self, path, ...) end,
local image = self.image
image:SetTexture(path) -- ["OnRelease"] = nil,
if image:GetTexture() then ["SetLabel"] = function(self, text)
self.imageshown = true if text and text ~= "" then
local n = select('#', ...) self.label:Show()
if n == 4 or n == 8 then self.label:SetText(text)
image:SetTexCoord(...) self:SetHeight(self.image:GetHeight() + 25)
else else
image:SetTexCoord(0, 1, 0, 1) self.label:Hide()
end self:SetHeight(self.image:GetHeight() + 10)
else end
self.imageshown = nil end,
end
end ["SetImage"] = function(self, path, ...)
local image = self.image
local function SetImageSize(self, width, height) image:SetTexture(path)
self.image:SetWidth(width)
self.image:SetHeight(height) if image:GetTexture() then
--self.frame:SetWidth(width + 30) local n = select("#", ...)
if self.label:IsShown() then if n == 4 or n == 8 then
self.frame:SetHeight(height + 25) image:SetTexCoord(...)
else else
self.frame:SetHeight(height + 10) image:SetTexCoord(0, 1, 0, 1)
end end
end end
end,
local function SetDisabled(self, disabled)
self.disabled = disabled ["SetImageSize"] = function(self, width, height)
if disabled then self.image:SetWidth(width)
self.frame:Disable() self.image:SetHeight(height)
self.label:SetTextColor(0.5,0.5,0.5) --self.frame:SetWidth(width + 30)
self.image:SetVertexColor(0.5, 0.5, 0.5, 0.5) if self.label:IsShown() then
else self:SetHeight(height + 25)
self.frame:Enable() else
self.label:SetTextColor(1,1,1) self:SetHeight(height + 10)
self.image:SetVertexColor(1, 1, 1) end
end end,
end
["SetDisabled"] = function(self, disabled)
local function OnClick(this, button) self.disabled = disabled
this.obj:Fire("OnClick", button) if disabled then
AceGUI:ClearFocus() self.frame:Disable()
end self.label:SetTextColor(0.5, 0.5, 0.5)
self.image:SetVertexColor(0.5, 0.5, 0.5, 0.5)
local function OnEnter(this) else
this.obj.highlight:Show() self.frame:Enable()
this.obj:Fire("OnEnter") self.label:SetTextColor(1, 1, 1)
end self.image:SetVertexColor(1, 1, 1, 1)
end
local function OnLeave(this) end
this.obj.highlight:Hide() }
this.obj:Fire("OnLeave")
end --[[-----------------------------------------------------------------------------
Constructor
local function Constructor() -------------------------------------------------------------------------------]]
local frame = CreateFrame("Button",nil,UIParent) local function Constructor()
local self = {} local frame = CreateFrame("Button", nil, UIParent)
self.type = Type frame:Hide()
self.OnRelease = OnRelease frame:EnableMouse(true)
self.OnAcquire = OnAcquire frame:SetScript("OnEnter", Control_OnEnter)
self.SetLabel = SetLabel frame:SetScript("OnLeave", Control_OnLeave)
self.frame = frame frame:SetScript("OnClick", Button_OnClick)
self.SetImage = SetImage
self.SetImageSize = SetImageSize local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontHighlight")
label:SetPoint("BOTTOMLEFT")
-- SetText should be deprecated along the way label:SetPoint("BOTTOMRIGHT")
self.SetText = SetLabel label:SetJustifyH("CENTER")
self.SetDisabled = SetDisabled label:SetJustifyV("TOP")
label:SetHeight(18)
frame.obj = self
local image = frame:CreateTexture(nil, "BACKGROUND")
frame:SetHeight(110) image:SetWidth(64)
frame:SetWidth(110) image:SetHeight(64)
frame:EnableMouse(true) image:SetPoint("TOP", 0, -5)
frame:SetScript("OnClick", OnClick)
frame:SetScript("OnLeave", OnLeave) local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
frame:SetScript("OnEnter", OnEnter) highlight:SetAllPoints(image)
local label = frame:CreateFontString(nil,"BACKGROUND","GameFontHighlight") highlight:SetTexture(136580) -- Interface\\PaperDollInfoFrame\\UI-Character-Tab-Highlight
label:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,0) highlight:SetTexCoord(0, 1, 0.23, 0.77)
label:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0) highlight:SetBlendMode("ADD")
label:SetJustifyH("CENTER")
label:SetJustifyV("TOP") local widget = {
label:SetHeight(18) label = label,
self.label = label image = image,
frame = frame,
local image = frame:CreateTexture(nil,"BACKGROUND") type = Type
self.image = image }
image:SetWidth(64) for method, func in pairs(methods) do
image:SetHeight(64) widget[method] = func
image:SetPoint("TOP",frame,"TOP",0,-5) end
local highlight = frame:CreateTexture(nil,"OVERLAY") widget.SetText = function(self, ...) print("AceGUI-3.0-Icon: SetText is deprecated! Use SetLabel instead!"); self:SetLabel(...) end
self.highlight = highlight
highlight:SetAllPoints(image) return AceGUI:RegisterAsWidget(widget)
highlight:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-Tab-Highlight") end
highlight:SetTexCoord(0,1,0.23,0.77)
highlight:SetBlendMode("ADD") AceGUI:RegisterWidgetType(Type, Constructor, Version)
highlight:Hide()
AceGUI:RegisterAsWidget(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
@@ -1,138 +0,0 @@
local AceGUI = LibStub("AceGUI-3.0")
-- WoW APIs
local CreateFrame, UIParent = CreateFrame, UIParent
-------------
-- Widgets --
-------------
--[[
Widgets must provide the following functions
Acquire() - Called when the object is aquired, should set everything to a default hidden state
Release() - Called when the object is Released, should remove any anchors and hide the Widget
And the following members
frame - the frame or derivitive object that will be treated as the widget for size and anchoring purposes
type - the type of the object, same as the name given to :RegisterWidget()
Widgets contain a table called userdata, this is a safe place to store data associated with the wigdet
It will be cleared automatically when a widget is released
Placing values directly into a widget object should be avoided
If the Widget can act as a container for other Widgets the following
content - frame or derivitive that children will be anchored to
The Widget can supply the following Optional Members
]]
--------------------------
-- Inline Group --
--------------------------
--[[
This is a simple grouping container, no selection
It will resize automatically to the height of the controls added to it
]]
do
local Type = "InlineGroup"
local Version = 6
local function OnAcquire(self)
self:SetWidth(300)
self:SetHeight(100)
end
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
end
local PaneBackdrop = {
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 16,
insets = { left = 3, right = 3, top = 5, bottom = 3 }
}
local function SetTitle(self,title)
self.titletext:SetText(title)
end
local function LayoutFinished(self, width, height)
if self.noAutoHeight then return end
self:SetHeight((height or 0) + 40)
end
local function OnWidthSet(self, width)
local content = self.content
local contentwidth = width - 20
if contentwidth < 0 then
contentwidth = 0
end
content:SetWidth(contentwidth)
content.width = contentwidth
end
local function OnHeightSet(self, height)
local content = self.content
local contentheight = height - 20
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = Type
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.SetTitle = SetTitle
self.frame = frame
self.LayoutFinished = LayoutFinished
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
frame.obj = self
frame:SetHeight(100)
frame:SetWidth(100)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
local titletext = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
titletext:SetPoint("TOPLEFT",frame,"TOPLEFT",14,0)
titletext:SetPoint("TOPRIGHT",frame,"TOPRIGHT",-14,0)
titletext:SetJustifyH("LEFT")
titletext:SetHeight(18)
self.titletext = titletext
local border = CreateFrame("Frame",nil,frame)
self.border = border
border:SetPoint("TOPLEFT",frame,"TOPLEFT",0,-17)
border:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-1,3)
border:SetBackdrop(PaneBackdrop)
border:SetBackdropColor(0.1,0.1,0.1,0.5)
border:SetBackdropBorderColor(0.4,0.4,0.4)
--Container Support
local content = CreateFrame("Frame",nil,border)
self.content = content
content.obj = self
content:SetPoint("TOPLEFT",border,"TOPLEFT",10,-10)
content:SetPoint("BOTTOMRIGHT",border,"BOTTOMRIGHT",-10,10)
AceGUI:RegisterAsContainer(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
@@ -1,219 +1,94 @@
local AceGUI = LibStub("AceGUI-3.0") --[[-----------------------------------------------------------------------------
InteractiveLabel Widget
-- Lua APIs -------------------------------------------------------------------------------]]
local select, max = select, math.max local Type, Version = "InteractiveLabel", 21
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
-- WoW APIs if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
local CreateFrame, UIParent = CreateFrame, UIParent
-- Lua APIs
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded local select, pairs = select, pairs
-- List them here for Mikk's FindGlobals script
-- GLOBALS: GameFontHighlightSmall --[[-----------------------------------------------------------------------------
Scripts
-------------------------- -------------------------------------------------------------------------------]]
-- Label -- local function Control_OnEnter(frame)
-------------------------- frame.obj:Fire("OnEnter")
do end
local Type = "InteractiveLabel"
local Version = 6 local function Control_OnLeave(frame)
frame.obj:Fire("OnLeave")
local function OnAcquire(self) end
self:SetHeight(18)
self:SetWidth(200) local function Label_OnClick(frame, button)
self:SetText("") frame.obj:Fire("OnClick", button)
self:SetImage(nil) AceGUI:ClearFocus()
self:SetColor() end
self:SetFontObject()
self:SetHighlight() --[[-----------------------------------------------------------------------------
self:SetHighlightTexCoord() Methods
end -------------------------------------------------------------------------------]]
local methods = {
local function OnRelease(self) ["OnAcquire"] = function(self)
self:SetDisabled(false) self:LabelOnAcquire()
self.frame:ClearAllPoints() self:SetHighlight()
self.frame:Hide() self:SetHighlightTexCoord()
end self:SetDisabled(false)
end,
local function UpdateImageAnchor(self)
local width = self.frame.width or self.frame:GetWidth() or 0 -- ["OnRelease"] = nil,
local image = self.image
local label = self.label ["SetHighlight"] = function(self, ...)
local frame = self.frame self.highlight:SetTexture(...)
local height end,
label:ClearAllPoints() ["SetHighlightTexCoord"] = function(self, ...)
image:ClearAllPoints() local c = select("#", ...)
if c == 4 or c == 8 then
if self.imageshown then self.highlight:SetTexCoord(...)
local imagewidth = image:GetWidth() else
if (width - imagewidth) < 200 or (label:GetText() or "") == "" then self.highlight:SetTexCoord(0, 1, 0, 1)
--image goes on top centered when less than 200 width for the text, or if there is no text end
image:SetPoint("TOP",frame,"TOP",0,0) end,
label:SetPoint("TOP",image,"BOTTOM",0,0)
label:SetPoint("LEFT",frame,"LEFT",0,0) ["SetDisabled"] = function(self,disabled)
label:SetWidth(width) self.disabled = disabled
height = image:GetHeight() + label:GetHeight() if disabled then
else self.frame:EnableMouse(false)
--image on the left self.label:SetTextColor(0.5, 0.5, 0.5)
local imageheight = image:GetHeight() else
local labelheight = label:GetHeight() self.frame:EnableMouse(true)
--center image with label self.label:SetTextColor(1, 1, 1)
if imageheight > labelheight then end
image:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0) end
label:SetPoint("LEFT",image,"RIGHT",0,0) }
else
label:SetPoint("TOPLEFT",frame,"TOPLEFT",imagewidth,0) --[[-----------------------------------------------------------------------------
image:SetPoint("RIGHT",label,"LEFT",0,0) Constructor
end -------------------------------------------------------------------------------]]
label:SetWidth(width - imagewidth) local function Constructor()
height = max(imageheight, labelheight) -- create a Label type that we will hijack
end local label = AceGUI:Create("Label")
else
--no image shown local frame = label.frame
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0) frame:EnableMouse(true)
label:SetWidth(width) frame:SetScript("OnEnter", Control_OnEnter)
height = self.label:GetHeight() frame:SetScript("OnLeave", Control_OnLeave)
end frame:SetScript("OnMouseDown", Label_OnClick)
self.resizing = true local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
self.frame:SetHeight(height) highlight:SetTexture(nil)
self.frame.height = height highlight:SetAllPoints()
self.resizing = nil highlight:SetBlendMode("ADD")
end
label.highlight = highlight
local function SetText(self, text) label.type = Type
self.label:SetText(text or "") label.LabelOnAcquire = label.OnAcquire
UpdateImageAnchor(self) for method, func in pairs(methods) do
end label[method] = func
end
local function SetColor(self, r, g, b)
if not (r and g and b) then return label
r, g, b = 1, 1, 1 end
end
self.label:SetVertexColor(r, g, b) AceGUI:RegisterWidgetType(Type, Constructor, Version)
end
local function OnWidthSet(self, width)
if self.resizing then return end
UpdateImageAnchor(self)
end
local function SetImage(self, path, ...)
local image = self.image
image:SetTexture(path)
if image:GetTexture() then
self.imageshown = true
local n = select('#', ...)
if n == 4 or n == 8 then
image:SetTexCoord(...)
end
else
self.imageshown = nil
end
UpdateImageAnchor(self)
end
local function SetFont(self, font, height, flags)
self.label:SetFont(font, height, flags)
end
local function SetFontObject(self, font)
self.label:SetFontObject(font or GameFontHighlightSmall)
end
local function SetImageSize(self, width, height)
self.image:SetWidth(width)
self.image:SetHeight(height)
UpdateImageAnchor(self)
end
local function SetHighlight(self, ...)
self.highlight:SetTexture(...)
end
local function SetHighlightTexCoord(self, ...)
if select('#', ...) >= 1 then
self.highlight:SetTexCoord(...)
else
self.highlight:SetTexCoord(0, 1, 0, 1)
end
end
local function SetDisabled(self,disabled)
self.disabled = disabled
if disabled then
self.frame:EnableMouse(false)
self.label:SetTextColor(0.5, 0.5, 0.5)
else
self.frame:EnableMouse(true)
self.label:SetTextColor(1, 1, 1)
end
end
local function OnEnter(this)
this.obj.highlight:Show()
this.obj:Fire("OnEnter")
end
local function OnLeave(this)
this.obj.highlight:Hide()
this.obj:Fire("OnLeave")
end
local function OnClick(this, ...)
this.obj:Fire("OnClick", ...)
AceGUI:ClearFocus()
end
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = Type
frame:EnableMouse(true)
frame:SetScript("OnEnter", OnEnter)
frame:SetScript("OnLeave", OnLeave)
frame:SetScript("OnMouseDown", OnClick)
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.SetText = SetText
self.SetColor = SetColor
self.frame = frame
self.OnWidthSet = OnWidthSet
self.SetImage = SetImage
self.SetImageSize = SetImageSize
self.SetFont = SetFont
self.SetFontObject = SetFontObject
self.SetHighlight = SetHighlight
self.SetHighlightTexCoord = SetHighlightTexCoord
self.SetDisabled = SetDisabled
frame.obj = self
frame:SetHeight(18)
frame:SetWidth(200)
local label = frame:CreateFontString(nil,"BACKGROUND","GameFontHighlightSmall")
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
label:SetWidth(200)
label:SetJustifyH("LEFT")
label:SetJustifyV("TOP")
self.label = label
local highlight = frame:CreateTexture(nil, "OVERLAY")
highlight:SetTexture(nil)
highlight:SetAllPoints()
highlight:SetBlendMode("ADD")
highlight:Hide()
self.highlight = highlight
local image = frame:CreateTexture(nil,"BACKGROUND")
self.image = image
AceGUI:RegisterAsWidget(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
@@ -1,230 +1,251 @@
local AceGUI = LibStub("AceGUI-3.0") --[[-----------------------------------------------------------------------------
Keybinding Widget
-- Lua APIs Set Keybindings in the Config UI.
-------------------------------------------------------------------------------]]
-- WoW APIs local Type, Version = "Keybinding", 27
local IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown = IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
local CreateFrame, UIParent = CreateFrame, UIParent if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded -- Lua APIs
-- List them here for Mikk's FindGlobals script local pairs = pairs
-- GLOBALS: NOT_BOUND
-- WoW APIs
-------------------------- local IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown = IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown
-- Keybinding -- local CreateFrame, UIParent = CreateFrame, UIParent
--------------------------
--[[-----------------------------------------------------------------------------
do Scripts
local Type = "Keybinding" -------------------------------------------------------------------------------]]
local Version = 13
local function Control_OnEnter(frame)
local ControlBackdrop = { frame.obj:Fire("OnEnter")
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", end
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 16, local function Control_OnLeave(frame)
insets = { left = 3, right = 3, top = 3, bottom = 3 } frame.obj:Fire("OnLeave")
} end
local function Control_OnEnter(this) local function Keybinding_OnClick(frame, button)
this.obj:Fire("OnEnter") if button == "LeftButton" or button == "RightButton" then
end local self = frame.obj
if self.waitingForKey then
local function Control_OnLeave(this) frame:EnableKeyboard(false)
this.obj:Fire("OnLeave") frame:EnableMouseWheel(false)
end frame:EnableGamePadButton(false)
self.msgframe:Hide()
local function keybindingMsgFixWidth(this) frame:UnlockHighlight()
this:SetWidth(this.msg:GetWidth()+10) self.waitingForKey = nil
this:SetScript("OnUpdate",nil) else
end frame:EnableKeyboard(true)
frame:EnableMouseWheel(true)
local function Keybinding_OnClick(this, button) frame:EnableGamePadButton(true)
if button == "LeftButton" or button == "RightButton" then self.msgframe:Show()
local self = this.obj frame:LockHighlight()
if self.waitingForKey then self.waitingForKey = true
this:EnableKeyboard(false) end
self.msgframe:Hide() end
this:UnlockHighlight() AceGUI:ClearFocus()
self.waitingForKey = nil end
else
this:EnableKeyboard(true) local ignoreKeys = {
self.msgframe:Show() ["BUTTON1"] = true, ["BUTTON2"] = true,
this:LockHighlight() ["UNKNOWN"] = true,
self.waitingForKey = true ["LSHIFT"] = true, ["LCTRL"] = true, ["LALT"] = true,
end ["RSHIFT"] = true, ["RCTRL"] = true, ["RALT"] = true,
end }
AceGUI:ClearFocus() local function Keybinding_OnKeyDown(frame, key)
end local self = frame.obj
if self.waitingForKey then
local ignoreKeys = nil local keyPressed = key
local function Keybinding_OnKeyDown(this, key) if keyPressed == "ESCAPE" then
local self = this.obj keyPressed = ""
if self.waitingForKey then else
local keyPressed = key if ignoreKeys[keyPressed] then return end
if keyPressed == "ESCAPE" then if IsShiftKeyDown() then
keyPressed = "" keyPressed = "SHIFT-"..keyPressed
else end
if not ignoreKeys then if IsControlKeyDown() then
ignoreKeys = { keyPressed = "CTRL-"..keyPressed
["BUTTON1"] = true, ["BUTTON2"] = true, end
["UNKNOWN"] = true, if IsAltKeyDown() then
["LSHIFT"] = true, ["LCTRL"] = true, ["LALT"] = true, keyPressed = "ALT-"..keyPressed
["RSHIFT"] = true, ["RCTRL"] = true, ["RALT"] = true, end
} end
end
if ignoreKeys[keyPressed] then return end frame:EnableKeyboard(false)
if IsShiftKeyDown() then frame:EnableMouseWheel(false)
keyPressed = "SHIFT-"..keyPressed frame:EnableGamePadButton(false)
end self.msgframe:Hide()
if IsControlKeyDown() then frame:UnlockHighlight()
keyPressed = "CTRL-"..keyPressed self.waitingForKey = nil
end
if IsAltKeyDown() then if not self.disabled then
keyPressed = "ALT-"..keyPressed self:SetKey(keyPressed)
end self:Fire("OnKeyChanged", keyPressed)
end end
end
this:EnableKeyboard(false) end
self.msgframe:Hide()
this:UnlockHighlight() local function Keybinding_OnMouseDown(frame, button)
self.waitingForKey = nil if button == "LeftButton" or button == "RightButton" then
return
if not self.disabled then elseif button == "MiddleButton" then
self:SetKey(keyPressed) button = "BUTTON3"
self:Fire("OnKeyChanged",keyPressed) elseif button == "Button4" then
end button = "BUTTON4"
end elseif button == "Button5" then
end button = "BUTTON5"
end
local function Keybinding_OnMouseDown(this, button) Keybinding_OnKeyDown(frame, button)
if button == "LeftButton" or button == "RightButton" then end
return
elseif button == "MiddleButton" then local function Keybinding_OnMouseWheel(frame, direction)
button = "BUTTON3" local button
elseif button == "Button4" then if direction >= 0 then
button = "BUTTON4" button = "MOUSEWHEELUP"
elseif button == "Button5" then else
button = "BUTTON5" button = "MOUSEWHEELDOWN"
end end
Keybinding_OnKeyDown(this, button) Keybinding_OnKeyDown(frame, button)
end end
local function OnAcquire(self) --[[-----------------------------------------------------------------------------
self:SetWidth(200) Methods
self:SetHeight(44) -------------------------------------------------------------------------------]]
self:SetLabel("") local methods = {
self:SetKey("") ["OnAcquire"] = function(self)
end self:SetWidth(200)
self:SetLabel("")
local function OnRelease(self) self:SetKey("")
self.frame:ClearAllPoints() self.waitingForKey = nil
self.frame:Hide() self.msgframe:Hide()
self.waitingForKey = nil self:SetDisabled(false)
self.msgframe:Hide() self.button:EnableKeyboard(false)
self:SetDisabled(false) self.button:EnableMouseWheel(false)
end self.button:EnableGamePadButton(false)
end,
local function SetDisabled(self, disabled)
self.disabled = disabled -- ["OnRelease"] = nil,
if disabled then
self.button:Disable() ["SetDisabled"] = function(self, disabled)
self.label:SetTextColor(0.5,0.5,0.5) self.disabled = disabled
else if disabled then
self.button:Enable() self.button:Disable()
self.label:SetTextColor(1,1,1) self.label:SetTextColor(0.5,0.5,0.5)
end else
end self.button:Enable()
self.label:SetTextColor(1,1,1)
local function SetKey(self, key) end
if (key or "") == "" then end,
self.button:SetText(NOT_BOUND)
self.button:SetNormalFontObject("GameFontNormal") ["SetKey"] = function(self, key)
else if (key or "") == "" then
self.button:SetText(key) self.button:SetText(NOT_BOUND)
self.button:SetNormalFontObject("GameFontHighlight") self.button:SetNormalFontObject("GameFontNormal")
end else
end self.button:SetText(key)
self.button:SetNormalFontObject("GameFontHighlight")
local function SetLabel(self, label) end
self.label:SetText(label or "") end,
if (label or "") == "" then
self.alignoffset = nil ["GetKey"] = function(self)
self:SetHeight(24) local key = self.button:GetText()
else if key == NOT_BOUND then
self.alignoffset = 30 key = nil
self:SetHeight(44) end
end return key
end end,
local function Constructor() ["SetLabel"] = function(self, label)
local num = AceGUI:GetNextWidgetNum(Type) self.label:SetText(label or "")
local frame = CreateFrame("Frame",nil,UIParent) if (label or "") == "" then
self.alignoffset = nil
local button = CreateFrame("Button","AceGUI-3.0 KeybindingButton"..num,frame,"UIPanelButtonTemplate2") self:SetHeight(24)
else
local self = {} self.alignoffset = 30
self.type = Type self:SetHeight(44)
self.num = num end
end,
local text = button:GetFontString() }
text:SetPoint("LEFT",button,"LEFT",7,0)
text:SetPoint("RIGHT",button,"RIGHT",-7,0) --[[-----------------------------------------------------------------------------
Constructor
button:SetScript("OnClick",Keybinding_OnClick) -------------------------------------------------------------------------------]]
button:SetScript("OnKeyDown",Keybinding_OnKeyDown)
button:SetScript("OnEnter",Control_OnEnter) local ControlBackdrop = {
button:SetScript("OnLeave",Control_OnLeave) bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
button:SetScript("OnMouseDown",Keybinding_OnMouseDown) edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
button:RegisterForClicks("AnyDown") tile = true, tileSize = 16, edgeSize = 16,
button:EnableMouse() insets = { left = 3, right = 3, top = 3, bottom = 3 }
}
button:SetHeight(24)
button:SetWidth(200) local function keybindingMsgFixWidth(frame)
button:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT",0,0) frame:SetWidth(frame.msg:GetWidth() + 10)
button:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0) frame:SetScript("OnUpdate", nil)
end
frame:SetWidth(200)
frame:SetHeight(44) local function Constructor()
local name = "AceGUI30KeybindingButton" .. AceGUI:GetNextWidgetNum(Type)
self.alignoffset = 30
local frame = CreateFrame("Frame", nil, UIParent)
self.button = button local button = CreateFrame("Button", name, frame, "UIPanelButtonTemplate")
local label = frame:CreateFontString(nil,"OVERLAY","GameFontHighlight") button:EnableMouse(true)
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0) button:EnableMouseWheel(false)
label:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0) button:RegisterForClicks("AnyDown")
label:SetJustifyH("CENTER") button:SetScript("OnEnter", Control_OnEnter)
label:SetHeight(18) button:SetScript("OnLeave", Control_OnLeave)
self.label = label button:SetScript("OnClick", Keybinding_OnClick)
button:SetScript("OnKeyDown", Keybinding_OnKeyDown)
local msgframe = CreateFrame("Frame",nil,UIParent) button:SetScript("OnMouseDown", Keybinding_OnMouseDown)
msgframe:SetHeight(30) button:SetScript("OnMouseWheel", Keybinding_OnMouseWheel)
msgframe:SetBackdrop(ControlBackdrop) button:SetScript("OnGamePadButtonDown", Keybinding_OnKeyDown)
msgframe:SetBackdropColor(0,0,0) button:SetPoint("BOTTOMLEFT")
msgframe:SetFrameStrata("FULLSCREEN_DIALOG") button:SetPoint("BOTTOMRIGHT")
msgframe:SetFrameLevel(1000) button:SetHeight(24)
self.msgframe = msgframe button:EnableKeyboard(false)
local msg = msgframe:CreateFontString(nil,"OVERLAY","GameFontNormal") button:EnableGamePadButton(false)
msg:SetText("Press a key to bind, ESC to clear the binding or click the button again to cancel")
msgframe.msg = msg local text = button:GetFontString()
msg:SetPoint("TOPLEFT",msgframe,"TOPLEFT",5,-5) text:SetPoint("LEFT", 7, 0)
msgframe:SetScript("OnUpdate", keybindingMsgFixWidth) text:SetPoint("RIGHT", -7, 0)
msgframe:SetPoint("BOTTOM",button,"TOP",0,0)
msgframe:Hide() local label = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
label:SetPoint("TOPLEFT")
self.OnRelease = OnRelease label:SetPoint("TOPRIGHT")
self.OnAcquire = OnAcquire label:SetJustifyH("CENTER")
self.SetLabel = SetLabel label:SetHeight(18)
self.SetDisabled = SetDisabled
self.SetKey = SetKey local msgframe = CreateFrame("Frame", nil, UIParent, "BackdropTemplate")
msgframe:SetHeight(30)
self.frame = frame msgframe:SetBackdrop(ControlBackdrop)
frame.obj = self msgframe:SetBackdropColor(0,0,0)
button.obj = self msgframe:SetFrameStrata("FULLSCREEN_DIALOG")
msgframe:SetFrameLevel(1000)
AceGUI:RegisterAsWidget(self) msgframe:SetToplevel(true)
return self
end local msg = msgframe:CreateFontString(nil, "OVERLAY", "GameFontNormal")
msg:SetText("Press a key to bind, ESC to clear the binding or click the button again to cancel.")
AceGUI:RegisterWidgetType(Type,Constructor,Version) msgframe.msg = msg
end msg:SetPoint("TOPLEFT", 5, -5)
msgframe:SetScript("OnUpdate", keybindingMsgFixWidth)
msgframe:SetPoint("BOTTOM", button, "TOP")
msgframe:Hide()
local widget = {
button = button,
label = label,
msgframe = msgframe,
frame = frame,
alignoffset = 30,
type = Type
}
for method, func in pairs(methods) do
widget[method] = func
end
button.obj = widget
return AceGUI:RegisterAsWidget(widget)
end
AceGUI:RegisterWidgetType(Type, Constructor, Version)
+179 -155
View File
@@ -1,155 +1,179 @@
local AceGUI = LibStub("AceGUI-3.0") --[[-----------------------------------------------------------------------------
Label Widget
-- Lua APIs Displays text and optionally an icon.
local max, select = math.max, select -------------------------------------------------------------------------------]]
local Type, Version = "Label", 28
-- WoW APIs local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
local CreateFrame, UIParent = CreateFrame, UIParent if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded -- Lua APIs
-- List them here for Mikk's FindGlobals script local max, select, pairs = math.max, select, pairs
-- GLOBALS: GameFontHighlightSmall
-- WoW APIs
-------------------------- local CreateFrame, UIParent = CreateFrame, UIParent
-- Label --
-------------------------- --[[-----------------------------------------------------------------------------
do Support functions
local Type = "Label" -------------------------------------------------------------------------------]]
local Version = 11
local function UpdateImageAnchor(self)
local function OnAcquire(self) if self.resizing then return end
self:SetHeight(18) local frame = self.frame
self:SetWidth(200) local width = frame.width or frame:GetWidth() or 0
self:SetText("") local image = self.image
self:SetImage(nil) local label = self.label
self:SetColor() local height
self:SetFontObject()
end label:ClearAllPoints()
image:ClearAllPoints()
local function OnRelease(self)
self.frame:ClearAllPoints() if self.imageshown then
self.frame:Hide() local imagewidth = image:GetWidth()
end if (width - imagewidth) < 200 or (label:GetText() or "") == "" then
-- image goes on top centered when less than 200 width for the text, or if there is no text
local function UpdateImageAnchor(self) image:SetPoint("TOP")
local width = self.frame.width or self.frame:GetWidth() or 0 label:SetPoint("TOP", image, "BOTTOM")
local image = self.image label:SetPoint("LEFT")
local label = self.label label:SetWidth(width)
local frame = self.frame height = image:GetHeight() + label:GetStringHeight()
local height else
-- image on the left
label:ClearAllPoints() image:SetPoint("TOPLEFT")
image:ClearAllPoints() if image:GetHeight() > label:GetStringHeight() then
label:SetPoint("LEFT", image, "RIGHT", 4, 0)
if self.imageshown then else
local imagewidth = image:GetWidth() label:SetPoint("TOPLEFT", image, "TOPRIGHT", 4, 0)
if (width - imagewidth) < 200 or (label:GetText() or "") == "" then end
--image goes on top centered when less than 200 width for the text, or if there is no text label:SetWidth(width - imagewidth - 4)
image:SetPoint("TOP",frame,"TOP",0,0) height = max(image:GetHeight(), label:GetStringHeight())
label:SetPoint("TOP",image,"BOTTOM",0,0) end
label:SetPoint("LEFT",frame,"LEFT",0,0) else
label:SetWidth(width) -- no image shown
height = image:GetHeight() + label:GetHeight() label:SetPoint("TOPLEFT")
else label:SetWidth(width)
--image on the left height = label:GetStringHeight()
image:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0) end
label:SetPoint("TOPLEFT",image,"TOPRIGHT",4,0)
label:SetWidth(width - imagewidth) -- avoid zero-height labels, since they can used as spacers
height = max(image:GetHeight(), label:GetHeight()) if not height or height == 0 then
end height = 1
else end
--no image shown
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0) self.resizing = true
label:SetWidth(width) frame:SetHeight(height)
height = self.label:GetHeight() frame.height = height
end self.resizing = nil
end
self.resizing = true
self.frame:SetHeight(height) --[[-----------------------------------------------------------------------------
self.frame.height = height Methods
self.resizing = nil -------------------------------------------------------------------------------]]
end local methods = {
["OnAcquire"] = function(self)
local function SetText(self, text) -- set the flag to stop constant size updates
self.label:SetText(text or "") self.resizing = true
UpdateImageAnchor(self) -- height is set dynamically by the text and image size
end self:SetWidth(200)
self:SetText()
local function SetColor(self, r, g, b) self:SetImage(nil)
if not (r and g and b) then self:SetImageSize(16, 16)
r, g, b = 1, 1, 1 self:SetColor()
end self:SetFontObject()
self.label:SetVertexColor(r, g, b) self:SetJustifyH("LEFT")
end self:SetJustifyV("TOP")
local function OnWidthSet(self, width) -- reset the flag
if self.resizing then return end self.resizing = nil
UpdateImageAnchor(self) -- run the update explicitly
end UpdateImageAnchor(self)
end,
local function SetImage(self, path, ...)
local image = self.image -- ["OnRelease"] = nil,
image:SetTexture(path)
["OnWidthSet"] = function(self, width)
if image:GetTexture() then UpdateImageAnchor(self)
self.imageshown = true end,
local n = select('#', ...)
if n == 4 or n == 8 then ["SetText"] = function(self, text)
image:SetTexCoord(...) self.label:SetText(text)
end UpdateImageAnchor(self)
else end,
self.imageshown = nil
end ["SetColor"] = function(self, r, g, b)
UpdateImageAnchor(self) if not (r and g and b) then
end r, g, b = 1, 1, 1
end
local function SetFont(self, font, height, flags) self.label:SetVertexColor(r, g, b)
self.label:SetFont(font, height, flags) end,
end
["SetImage"] = function(self, path, ...)
local function SetFontObject(self, font) local image = self.image
self.label:SetFontObject(font or GameFontHighlightSmall) image:SetTexture(path)
end
if image:GetTexture() then
local function SetImageSize(self, width, height) self.imageshown = true
self.image:SetWidth(width) local n = select("#", ...)
self.image:SetHeight(height) if n == 4 or n == 8 then
UpdateImageAnchor(self) image:SetTexCoord(...)
end else
image:SetTexCoord(0, 1, 0, 1)
local function Constructor() end
local frame = CreateFrame("Frame",nil,UIParent) else
local self = {} self.imageshown = nil
self.type = Type end
UpdateImageAnchor(self)
self.OnRelease = OnRelease end,
self.OnAcquire = OnAcquire
self.SetText = SetText ["SetFont"] = function(self, font, height, flags)
self.SetColor = SetColor if not self.fontObject then
self.frame = frame self.fontObject = CreateFont("AceGUI30LabelFont" .. AceGUI:GetNextWidgetNum(Type))
self.OnWidthSet = OnWidthSet end
self.SetImage = SetImage self.fontObject:SetFont(font, height, flags)
self.SetImageSize = SetImageSize self:SetFontObject(self.fontObject)
self.SetFont = SetFont end,
self.SetFontObject = SetFontObject
frame.obj = self ["SetFontObject"] = function(self, font)
self.label:SetFontObject(font or GameFontHighlightSmall)
frame:SetHeight(18) UpdateImageAnchor(self)
frame:SetWidth(200) end,
local label = frame:CreateFontString(nil,"BACKGROUND","GameFontHighlightSmall")
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0) ["SetImageSize"] = function(self, width, height)
label:SetWidth(200) self.image:SetWidth(width)
label:SetJustifyH("LEFT") self.image:SetHeight(height)
label:SetJustifyV("TOP") UpdateImageAnchor(self)
self.label = label end,
local image = frame:CreateTexture(nil,"BACKGROUND") ["SetJustifyH"] = function(self, justifyH)
self.image = image self.label:SetJustifyH(justifyH)
end,
AceGUI:RegisterAsWidget(self)
return self ["SetJustifyV"] = function(self, justifyV)
end self.label:SetJustifyV(justifyV)
end,
AceGUI:RegisterWidgetType(Type,Constructor,Version) }
end
--[[-----------------------------------------------------------------------------
Constructor
-------------------------------------------------------------------------------]]
local function Constructor()
local frame = CreateFrame("Frame", nil, UIParent)
frame:Hide()
local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontHighlightSmall")
local image = frame:CreateTexture(nil, "BACKGROUND")
-- create widget
local widget = {
label = label,
image = image,
frame = frame,
type = Type
}
for method, func in pairs(methods) do
widget[method] = func
end
return AceGUI:RegisterAsWidget(widget)
end
AceGUI:RegisterWidgetType(Type, Constructor, Version)
@@ -1,309 +1,377 @@
local Type, Version = "MultiLineEditBox", 33
--[[ local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
--Multiline Editbox Widget, Originally by bam if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
--]] -- Lua APIs
local AceGUI = LibStub("AceGUI-3.0") local pairs = pairs
-- Lua APIs -- WoW APIs
local format, pairs, tostring = string.format, pairs, tostring local GetCursorInfo, ClearCursor = GetCursorInfo, ClearCursor
local CreateFrame, UIParent = CreateFrame, UIParent
-- WoW APIs local _G = _G
local GetCursorInfo, ClearCursor, GetSpellName = GetCursorInfo, ClearCursor, GetSpellName
local CreateFrame, UIParent = CreateFrame, UIParent --[[-----------------------------------------------------------------------------
Support functions
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded -------------------------------------------------------------------------------]]
-- List them here for Mikk's FindGlobals script
-- GLOBALS: ChatFontNormal, ACCEPT if not AceGUIMultiLineEditBoxInsertLink then
-- upgradeable hook
local Version = 11 if ChatFrameUtil and ChatFrameUtil.InsertLink then
--------------------- hooksecurefunc(ChatFrameUtil, "InsertLink", function(...) return _G.AceGUIMultiLineEditBoxInsertLink(...) end)
-- Common Elements -- elseif ChatEdit_InsertLink then
--------------------- hooksecurefunc("ChatEdit_InsertLink", function(...) return _G.AceGUIMultiLineEditBoxInsertLink(...) end)
end
local FrameBackdrop = { end
bgFile="Interface\\DialogFrame\\UI-DialogBox-Background",
edgeFile="Interface\\DialogFrame\\UI-DialogBox-Border", function _G.AceGUIMultiLineEditBoxInsertLink(text)
tile = true, tileSize = 32, edgeSize = 32, for i = 1, AceGUI:GetWidgetCount(Type) do
insets = { left = 8, right = 8, top = 8, bottom = 8 } local editbox = _G[("MultiLineEditBox%uEdit"):format(i)]
} if editbox and editbox:IsVisible() and editbox:HasFocus() then
editbox:Insert(text)
local PaneBackdrop = { return true
end
bgFile = "Interface\\ChatFrame\\ChatFrameBackground", end
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", end
tile = true, tileSize = 16, edgeSize = 16,
insets = { left = 3, right = 3, top = 5, bottom = 3 }
} local function Layout(self)
self:SetHeight(self.numlines * 14 + (self.disablebutton and 19 or 41) + self.labelHeight)
local ControlBackdrop = {
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", if self.labelHeight == 0 then
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", self.scrollBar:SetPoint("TOP", self.frame, "TOP", 0, -23)
tile = true, tileSize = 16, edgeSize = 16, else
insets = { left = 3, right = 3, top = 3, bottom = 3 } self.scrollBar:SetPoint("TOP", self.label, "BOTTOM", 0, -19)
} end
-------------------------- if self.disablebutton then
-- Edit box -- self.scrollBar:SetPoint("BOTTOM", self.frame, "BOTTOM", 0, 21)
-------------------------- self.scrollBG:SetPoint("BOTTOMLEFT", 0, 4)
--[[ else
Events : self.scrollBar:SetPoint("BOTTOM", self.button, "TOP", 0, 18)
OnTextChanged self.scrollBG:SetPoint("BOTTOMLEFT", self.button, "TOPLEFT")
OnEnterPressed end
end
]]
do --[[-----------------------------------------------------------------------------
local Type = "MultiLineEditBox" Scripts
-------------------------------------------------------------------------------]]
local MultiLineEditBox = {} local function OnClick(self) -- Button
self = self.obj
local function EditBox_OnEnterPressed(this) self.editBox:ClearFocus()
local self = this.obj if not self:Fire("OnEnterPressed", self.editBox:GetText()) then
local value = this:GetText() self.button:Disable()
local cancel = self:Fire("OnEnterPressed",value) end
if not cancel then end
self.button:Disable()
end local function OnCursorChanged(self, _, y, _, cursorHeight) -- EditBox
end self, y = self.obj.scrollFrame, -y
local offset = self:GetVerticalScroll()
local function Button_OnClick(this) if y < offset then
local editbox = this.obj.editbox self:SetVerticalScroll(y)
editbox:ClearFocus() else
EditBox_OnEnterPressed(editbox) y = y + cursorHeight - self:GetHeight()
end if y > offset then
self:SetVerticalScroll(y)
local function EditBox_OnReceiveDrag(this) end
local self = this.obj end
local type, id, info = GetCursorInfo() end
if type == "item" then
self:SetText(info) local function OnEditFocusLost(self) -- EditBox
self:Fire("OnEnterPressed",info) self:HighlightText(0, 0)
ClearCursor() self.obj:Fire("OnEditFocusLost")
elseif type == "spell" then end
local name, rank = GetSpellName(id, info)
if rank and rank:match("%d") then local function OnEnter(self) -- EditBox / ScrollFrame
name = name.."("..rank..")" self = self.obj
end if not self.entered then
self:SetText(name) self.entered = true
self:Fire("OnEnterPressed",name) self:Fire("OnEnter")
ClearCursor() end
end end
--self.button:Disable()
AceGUI:ClearFocus() local function OnLeave(self) -- EditBox / ScrollFrame
end self = self.obj
if self.entered then
function MultiLineEditBox:OnAcquire() self.entered = nil
self:SetWidth(200) self:Fire("OnLeave")
self:SetHeight(116) end
self:SetNumLines(4) end
self:SetDisabled(false)
self:ShowButton(true) local function OnMouseUp(self) -- ScrollFrame
end self = self.obj.editBox
self:SetFocus()
function MultiLineEditBox:OnRelease() self:SetCursorPosition(self:GetNumLetters())
self.frame:ClearAllPoints() end
self.frame:Hide()
self:SetDisabled(false) local function OnReceiveDrag(self) -- EditBox / ScrollFrame
end local type, id, info, extra = GetCursorInfo()
if type == "spell" then
function MultiLineEditBox:SetDisabled(disabled) if C_Spell and C_Spell.GetSpellName then
self.disabled = disabled info = C_Spell.GetSpellName(extra)
if disabled then else
self.editbox:EnableMouse(false) info = GetSpellInfo(id, info)
self.scrollframe:EnableMouse(false) end
self.editbox:ClearFocus() elseif type ~= "item" then
self.editbox:SetTextColor(0.5, 0.5, 0.5) return
self.label:SetTextColor(0.5,0.5,0.5) end
self.button:Disable() ClearCursor()
else self = self.obj
self.editbox:EnableMouse(true) local editBox = self.editBox
self.scrollframe:EnableMouse(true) if not editBox:HasFocus() then
self.editbox:SetTextColor(1, 1, 1) editBox:SetFocus()
self.label:SetTextColor(1,.82,0) editBox:SetCursorPosition(editBox:GetNumLetters())
self.button:Enable() end
end editBox:Insert(info)
end self.button:Enable()
end
function MultiLineEditBox:SetText(text)
text = text or "" local function OnSizeChanged(self, width, height) -- ScrollFrame
local editbox = self.editbox self.obj.editBox:SetWidth(width)
local oldText = editbox:GetText() end
local dummy = format(" %s", text)
self.lasttext = dummy -- prevents OnTextChanged from firing local function OnTextChanged(self, userInput) -- EditBox
editbox:SetText(dummy) if userInput then
editbox:HighlightText(0, 1) self = self.obj
self.lasttext = oldText self:Fire("OnTextChanged", self.editBox:GetText())
editbox:Insert("") self.button:Enable()
end end
end
function MultiLineEditBox:SetLabel(text)
if (text or "") == "" then local function OnTextSet(self) -- EditBox
self.backdrop:SetPoint("TOPLEFT",self.frame,"TOPLEFT",0,0) self:HighlightText(0, 0)
self.label:Hide() self:SetCursorPosition(self:GetNumLetters())
self.label:SetText("") self:SetCursorPosition(0)
else self.obj.button:Disable()
self.backdrop:SetPoint("TOPLEFT",self.frame,"TOPLEFT",0,-20) end
self.label:Show()
self.label:SetText(text) local function OnVerticalScroll(self, offset) -- ScrollFrame
end local editBox = self.obj.editBox
end editBox:SetHitRectInsets(0, 0, offset, editBox:GetHeight() - offset - self:GetHeight())
end
function MultiLineEditBox:SetNumLines(number)
number = number or 4 local function OnScrollRangeChanged(self, xrange, yrange)
self:SetHeight(60 + (14*number)) if yrange == 0 then
end self.obj.editBox:SetHitRectInsets(0, 0, 0, 0)
else
function MultiLineEditBox:GetText() OnVerticalScroll(self, self:GetVerticalScroll())
return self.editbox:GetText() end
end end
function MultiLineEditBox:ShowButton(show) local function OnShowFocus(frame)
if show then frame.obj.editBox:SetFocus()
self.backdrop:SetPoint("BOTTOMRIGHT",self.frame,"BOTTOMRIGHT",0,22) frame:SetScript("OnShow", nil)
self.button:Show() end
else
self.backdrop:SetPoint("BOTTOMRIGHT",self.frame,"BOTTOMRIGHT",0,0) local function OnEditFocusGained(frame)
self.button:Hide() AceGUI:SetFocus(frame.obj)
end frame.obj:Fire("OnEditFocusGained")
end end
local function Constructor() --[[-----------------------------------------------------------------------------
local frame = CreateFrame("Frame", nil, UIParent) Methods
local backdrop = CreateFrame("Frame", nil, frame) -------------------------------------------------------------------------------]]
local self = {} local methods = {
for k, v in pairs(MultiLineEditBox) do self[k] = v end ["OnAcquire"] = function(self)
self.type = Type self.editBox:SetText("")
self.frame = frame self:SetDisabled(false)
self.backdrop = backdrop self:SetWidth(200)
frame.obj = self self:DisableButton(false)
self:SetNumLines()
backdrop:SetBackdrop(ControlBackdrop) self.entered = nil
backdrop:SetBackdropColor(0, 0, 0) self:SetMaxLetters(0)
backdrop:SetBackdropBorderColor(0.4, 0.4, 0.4) end,
backdrop:SetPoint("TOPLEFT",frame,"TOPLEFT",0, -20) ["OnRelease"] = function(self)
backdrop:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,22) self:ClearFocus()
end,
local scrollframe = CreateFrame("ScrollFrame", format("%s@%s@%s", Type, "ScrollFrame", tostring(self)), backdrop, "UIPanelScrollFrameTemplate")
scrollframe:SetPoint("TOPLEFT", 5, -6) ["SetDisabled"] = function(self, disabled)
scrollframe:SetPoint("BOTTOMRIGHT", -28, 6) local editBox = self.editBox
scrollframe.obj = self if disabled then
self.scrollframe = scrollframe editBox:ClearFocus()
editBox:EnableMouse(false)
--local scrollchild = CreateFrame("Frame", nil, scrollframe) editBox:SetTextColor(0.5, 0.5, 0.5)
--scrollframe:SetScrollChild(scrollchild) self.label:SetTextColor(0.5, 0.5, 0.5)
--scrollchild:SetHeight(2) self.scrollFrame:EnableMouse(false)
--scrollchild:SetWidth(2) self.button:Disable()
else
local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall") editBox:EnableMouse(true)
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,-2) editBox:SetTextColor(1, 1, 1)
label:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,-2) self.label:SetTextColor(1, 0.82, 0)
label:SetJustifyH("LEFT") self.scrollFrame:EnableMouse(true)
label:SetHeight(18) end
self.label = label end,
local editbox = CreateFrame("EditBox", nil, scrollframe) ["SetLabel"] = function(self, text)
self.editbox = editbox if text and text ~= "" then
editbox.obj = self self.label:SetText(text)
editbox:SetPoint("TOPLEFT") if self.labelHeight ~= 10 then
editbox:SetPoint("BOTTOMLEFT") self.labelHeight = 10
editbox:SetHeight(50) self.label:Show()
editbox:SetWidth(50) end
editbox:SetMultiLine(true) elseif self.labelHeight ~= 0 then
-- editbox:SetMaxLetters(7500) self.labelHeight = 0
editbox:SetTextInsets(5, 5, 3, 3) self.label:Hide()
editbox:EnableMouse(true) end
editbox:SetAutoFocus(false) Layout(self)
editbox:SetFontObject(ChatFontNormal) end,
scrollframe:SetScrollChild(editbox)
["SetNumLines"] = function(self, value)
local button = CreateFrame("Button",nil,scrollframe,"UIPanelButtonTemplate") if not value or value < 4 then
button:SetWidth(80) value = 4
button:SetHeight(20) end
button:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,2) self.numlines = value
button:SetText(ACCEPT) Layout(self)
button:SetScript("OnClick", Button_OnClick) end,
button:SetFrameLevel(editbox:GetFrameLevel() + 1)
button:Disable() ["SetText"] = function(self, text)
button:Hide() self.editBox:SetText(text)
self.button = button end,
button.obj = self
["GetText"] = function(self)
scrollframe:EnableMouse(true) return self.editBox:GetText()
scrollframe:SetScript("OnMouseUp", function() editbox:SetFocus() end) end,
scrollframe:SetScript("OnEnter", function(this) this.obj:Fire("OnEnter") end)
scrollframe:SetScript("OnLeave", function(this) this.obj:Fire("OnLeave") end) ["SetMaxLetters"] = function (self, num)
self.editBox:SetMaxLetters(num or 0)
editbox:SetScript("OnEnter", function(this) this.obj:Fire("OnEnter") end) end,
editbox:SetScript("OnLeave", function(this) this.obj:Fire("OnLeave") end)
["DisableButton"] = function(self, disabled)
local function FixSize() self.disablebutton = disabled
--scrollchild:SetHeight(scrollframe:GetHeight()) if disabled then
--scrollchild:SetWidth(scrollframe:GetWidth()) self.button:Hide()
editbox:SetWidth(scrollframe:GetWidth()) else
end self.button:Show()
scrollframe:SetScript("OnShow", FixSize) end
scrollframe:SetScript("OnSizeChanged", FixSize) Layout(self)
end,
editbox:SetScript("OnEscapePressed", editbox.ClearFocus)
editbox:SetScript("OnTextChanged", function(_, ...) ["ClearFocus"] = function(self)
scrollframe:UpdateScrollChildRect() self.editBox:ClearFocus()
local value = editbox:GetText() self.frame:SetScript("OnShow", nil)
if value ~= self.lasttext then end,
self:Fire("OnTextChanged", value)
self.lasttext = value ["SetFocus"] = function(self)
if not self.disabled then self.editBox:SetFocus()
self.button:Enable() if not self.frame:IsShown() then
end self.frame:SetScript("OnShow", OnShowFocus)
end end
end) end,
editbox:SetScript("OnReceiveDrag", EditBox_OnReceiveDrag) ["HighlightText"] = function(self, from, to)
editbox:SetScript("OnMouseDown", EditBox_OnReceiveDrag) self.editBox:HighlightText(from, to)
end,
do
local cursorOffset, cursorHeight ["GetCursorPosition"] = function(self)
local idleTime return self.editBox:GetCursorPosition()
local function FixScroll(_, elapsed) end,
if cursorOffset and cursorHeight then
idleTime = 0 ["SetCursorPosition"] = function(self, ...)
local height = scrollframe:GetHeight() return self.editBox:SetCursorPosition(...)
local range = scrollframe:GetVerticalScrollRange() end,
local scroll = scrollframe:GetVerticalScroll() }
local size = height + range
cursorOffset = -cursorOffset --[[-----------------------------------------------------------------------------
while cursorOffset < scroll do Constructor
scroll = scroll - (height / 2) -------------------------------------------------------------------------------]]
if scroll < 0 then scroll = 0 end local backdrop = {
scrollframe:SetVerticalScroll(scroll) bgFile = [[Interface\Tooltips\UI-Tooltip-Background]],
end edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]], edgeSize = 16,
while cursorOffset + cursorHeight > scroll + height and scroll < range do insets = { left = 4, right = 3, top = 4, bottom = 3 }
scroll = scroll + (height / 2) }
if scroll > range then scroll = range end
scrollframe:SetVerticalScroll(scroll) local function Constructor()
end local frame = CreateFrame("Frame", nil, UIParent)
elseif not idleTime or idleTime > 2 then frame:Hide()
frame:SetScript("OnUpdate", nil)
idleTime = nil local widgetNum = AceGUI:GetNextWidgetNum(Type)
else
idleTime = idleTime + elapsed local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
end label:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, -4)
cursorOffset = nil label:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, -4)
end label:SetJustifyH("LEFT")
editbox:SetScript("OnCursorChanged", function(_, x, y, w, h) label:SetText(ACCEPT)
cursorOffset, cursorHeight = y, h label:SetHeight(10)
if not idleTime then
frame:SetScript("OnUpdate", FixScroll) local button = CreateFrame("Button", ("%s%dButton"):format(Type, widgetNum), frame, "UIPanelButtonTemplate")
end button:SetPoint("BOTTOMLEFT", 0, 4)
end) button:SetHeight(22)
end button:SetWidth(label:GetStringWidth() + 24)
button:SetText(ACCEPT)
AceGUI:RegisterAsWidget(self) button:SetScript("OnClick", OnClick)
return self button:Disable()
end
local text = button:GetFontString()
AceGUI:RegisterWidgetType(Type, Constructor, Version) text:ClearAllPoints()
end text:SetPoint("TOPLEFT", button, "TOPLEFT", 5, -5)
text:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -5, 1)
text:SetJustifyV("MIDDLE")
local scrollBG = CreateFrame("Frame", nil, frame, "BackdropTemplate")
scrollBG:SetBackdrop(backdrop)
scrollBG:SetBackdropColor(0, 0, 0)
scrollBG:SetBackdropBorderColor(0.4, 0.4, 0.4)
local scrollFrame = CreateFrame("ScrollFrame", ("%s%dScrollFrame"):format(Type, widgetNum), frame, "UIPanelScrollFrameTemplate")
local scrollBar = _G[scrollFrame:GetName() .. "ScrollBar"]
scrollBar:ClearAllPoints()
scrollBar:SetPoint("TOP", label, "BOTTOM", 0, -19)
scrollBar:SetPoint("BOTTOM", button, "TOP", 0, 18)
scrollBar:SetPoint("RIGHT", frame, "RIGHT")
scrollBG:SetPoint("TOPRIGHT", scrollBar, "TOPLEFT", 0, 19)
scrollBG:SetPoint("BOTTOMLEFT", button, "TOPLEFT")
scrollFrame:SetPoint("TOPLEFT", scrollBG, "TOPLEFT", 5, -6)
scrollFrame:SetPoint("BOTTOMRIGHT", scrollBG, "BOTTOMRIGHT", -4, 4)
scrollFrame:SetScript("OnEnter", OnEnter)
scrollFrame:SetScript("OnLeave", OnLeave)
scrollFrame:SetScript("OnMouseUp", OnMouseUp)
scrollFrame:SetScript("OnReceiveDrag", OnReceiveDrag)
scrollFrame:SetScript("OnSizeChanged", OnSizeChanged)
scrollFrame:HookScript("OnVerticalScroll", OnVerticalScroll)
scrollFrame:HookScript("OnScrollRangeChanged", OnScrollRangeChanged)
local editBox = CreateFrame("EditBox", ("%s%dEdit"):format(Type, widgetNum), scrollFrame)
editBox:SetAllPoints()
editBox:SetFontObject(ChatFontNormal)
editBox:SetMultiLine(true)
editBox:EnableMouse(true)
editBox:SetAutoFocus(false)
editBox:SetCountInvisibleLetters(false)
editBox:SetScript("OnCursorChanged", OnCursorChanged)
editBox:SetScript("OnEditFocusLost", OnEditFocusLost)
editBox:SetScript("OnEnter", OnEnter)
editBox:SetScript("OnEscapePressed", editBox.ClearFocus)
editBox:SetScript("OnLeave", OnLeave)
editBox:SetScript("OnMouseDown", OnReceiveDrag)
editBox:SetScript("OnReceiveDrag", OnReceiveDrag)
editBox:SetScript("OnTextChanged", OnTextChanged)
editBox:SetScript("OnTextSet", OnTextSet)
editBox:SetScript("OnEditFocusGained", OnEditFocusGained)
scrollFrame:SetScrollChild(editBox)
local widget = {
button = button,
editBox = editBox,
frame = frame,
label = label,
labelHeight = 10,
numlines = 4,
scrollBar = scrollBar,
scrollBG = scrollBG,
scrollFrame = scrollFrame,
type = Type
}
for method, func in pairs(methods) do
widget[method] = func
end
button.obj, editBox.obj, scrollFrame.obj = widget, widget, widget
return AceGUI:RegisterAsWidget(widget)
end
AceGUI:RegisterWidgetType(Type, Constructor, Version)
@@ -1,241 +0,0 @@
local AceGUI = LibStub("AceGUI-3.0")
-- Lua APIs
local pairs, assert, type = pairs, assert, type
local min, max, floor = math.min, math.max, math.floor
-- WoW APIs
local CreateFrame, UIParent = CreateFrame, UIParent
-------------
-- Widgets --
-------------
--[[
Widgets must provide the following functions
Acquire() - Called when the object is aquired, should set everything to a default hidden state
Release() - Called when the object is Released, should remove any anchors and hide the Widget
And the following members
frame - the frame or derivitive object that will be treated as the widget for size and anchoring purposes
type - the type of the object, same as the name given to :RegisterWidget()
Widgets contain a table called userdata, this is a safe place to store data associated with the wigdet
It will be cleared automatically when a widget is released
Placing values directly into a widget object should be avoided
If the Widget can act as a container for other Widgets the following
content - frame or derivitive that children will be anchored to
The Widget can supply the following Optional Members
]]
--------------------------
-- Scroll Frame --
--------------------------
do
local Type = "ScrollFrame"
local Version = 9
local function OnAcquire(self)
end
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
self.status = nil
-- do SetScroll after niling status, but before clearing localstatus
-- so the scroll value isnt populated back into status, but not kept in localstatus either
self:SetScroll(0)
for k in pairs(self.localstatus) do
self.localstatus[k] = nil
end
self.scrollframe:SetPoint("BOTTOMRIGHT",self.frame,"BOTTOMRIGHT",0,0)
self.scrollbar:Hide()
self.scrollBarShown = nil
self.content.height, self.content.width = nil, nil
end
local function SetScroll(self, value)
local status = self.status or self.localstatus
local viewheight = self.scrollframe:GetHeight()
local height = self.content:GetHeight()
local offset
if viewheight > height then
offset = 0
else
offset = floor((height - viewheight) / 1000.0 * value)
end
self.content:ClearAllPoints()
self.content:SetPoint("TOPLEFT", self.scrollframe, "TOPLEFT", 0, offset)
self.content:SetPoint("TOPRIGHT", self.scrollframe, "TOPRIGHT", 0, offset)
status.offset = offset
status.scrollvalue = value
end
local function MoveScroll(self, value)
local status = self.status or self.localstatus
local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
if height > viewheight then
self.scrollbar:Hide()
else
self.scrollbar:Show()
local diff = height - viewheight
local delta = 1
if value < 0 then
delta = -1
end
self.scrollbar:SetValue(min(max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000))
end
end
local function FixScroll(self)
if self.updateLock then return end
self.updateLock = true
local status = self.status or self.localstatus
local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
local offset = status.offset or 0
local curvalue = self.scrollbar:GetValue()
if viewheight < height then
if self.scrollBarShown then
self.scrollBarShown = nil
self.scrollbar:Hide()
self.scrollbar:SetValue(0)
self.scrollframe:SetPoint("BOTTOMRIGHT",self.frame,"BOTTOMRIGHT",0,0)
self:DoLayout()
end
else
if not self.scrollBarShown then
self.scrollBarShown = true
self.scrollbar:Show()
self.scrollframe:SetPoint("BOTTOMRIGHT", self.frame,"BOTTOMRIGHT",-20,0)
self:DoLayout()
end
local value = (offset / (viewheight - height) * 1000)
if value > 1000 then value = 1000 end
self.scrollbar:SetValue(value)
self:SetScroll(value)
if value < 1000 then
self.content:ClearAllPoints()
self.content:SetPoint("TOPLEFT", self.scrollframe, "TOPLEFT", 0, offset)
self.content:SetPoint("TOPRIGHT", self.scrollframe, "TOPRIGHT", 0, offset)
status.offset = offset
end
end
self.updateLock = nil
end
local function OnMouseWheel(this, value)
this.obj:MoveScroll(value)
end
local function OnScrollValueChanged(this, value)
this.obj:SetScroll(value)
end
local function FixScrollOnUpdate(this)
this:SetScript("OnUpdate", nil)
this.obj:FixScroll()
end
local function OnSizeChanged(this)
this:SetScript("OnUpdate", FixScrollOnUpdate)
end
local function LayoutFinished(self, width, height)
self.content:SetHeight(height or 0 + 20)
self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate)
end
-- called to set an external table to store status in
local function SetStatusTable(self, status)
assert(type(status) == "table")
self.status = status
if not status.scrollvalue then
status.scrollvalue = 0
end
end
local function OnWidthSet(self, width)
local content = self.content
content.width = width
end
local function OnHeightSet(self, height)
local content = self.content
content.height = height
end
local function Constructor()
local frame = CreateFrame("Frame", nil, UIParent)
local self = {}
self.type = Type
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.MoveScroll = MoveScroll
self.FixScroll = FixScroll
self.SetScroll = SetScroll
self.LayoutFinished = LayoutFinished
self.SetStatusTable = SetStatusTable
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
self.localstatus = {}
self.frame = frame
frame.obj = self
--Container Support
local scrollframe = CreateFrame("ScrollFrame", nil, frame)
scrollframe.obj = self
scrollframe:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, 0)
scrollframe:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 0, 0)
scrollframe:EnableMouseWheel(true)
scrollframe:SetScript("OnMouseWheel", OnMouseWheel)
scrollframe:SetScript("OnSizeChanged", OnSizeChanged)
self.scrollframe = scrollframe
local content = CreateFrame("Frame", nil, scrollframe)
content.obj = self
content:SetPoint("TOPLEFT", scrollframe, "TOPLEFT", 0, 0)
content:SetPoint("TOPRIGHT", scrollframe, "TOPRIGHT", 0, 0)
content:SetHeight(400)
self.content = content
scrollframe:SetScrollChild(content)
local num = AceGUI:GetNextWidgetNum(Type)
local name = ("AceConfigDialogScrollFrame%dScrollBar"):format(num)
local scrollbar = CreateFrame("Slider", name, scrollframe, "UIPanelScrollBarTemplate")
scrollbar.obj = self
scrollbar:SetPoint("TOPLEFT", scrollframe, "TOPRIGHT", 4, -16)
scrollbar:SetPoint("BOTTOMLEFT", scrollframe, "BOTTOMRIGHT", 4, 16)
scrollbar:SetScript("OnValueChanged", OnScrollValueChanged)
scrollbar:SetMinMaxValues(0, 1000)
scrollbar:SetValueStep(1)
scrollbar:SetValue(0)
scrollbar:SetWidth(16)
scrollbar:Hide()
self.scrollbar = scrollbar
local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND")
scrollbg:SetAllPoints(scrollbar)
scrollbg:SetTexture(0, 0, 0, 0.4)
self.localstatus.scrollvalue = 0
--self:FixScroll()
AceGUI:RegisterAsContainer(self)
--AceGUI:RegisterAsWidget(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
@@ -1,99 +0,0 @@
local AceGUI = LibStub("AceGUI-3.0")
-- WoW APIs
local CreateFrame, UIParent = CreateFrame, UIParent
-------------
-- Widgets --
-------------
--[[
Widgets must provide the following functions
Acquire() - Called when the object is aquired, should set everything to a default hidden state
Release() - Called when the object is Released, should remove any anchors and hide the Widget
And the following members
frame - the frame or derivitive object that will be treated as the widget for size and anchoring purposes
type - the type of the object, same as the name given to :RegisterWidget()
Widgets contain a table called userdata, this is a safe place to store data associated with the wigdet
It will be cleared automatically when a widget is released
Placing values directly into a widget object should be avoided
If the Widget can act as a container for other Widgets the following
content - frame or derivitive that children will be anchored to
The Widget can supply the following Optional Members
]]
--------------------------
-- Simple Group --
--------------------------
--[[
This is a simple grouping container, no selection, no borders
It will resize automatically to the height of the controls added to it
]]
do
local Type = "SimpleGroup"
local Version = 5
local function OnAcquire(self)
self:SetWidth(300)
self:SetHeight(100)
end
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
end
local function LayoutFinished(self, width, height)
if self.noAutoHeight then return end
self:SetHeight(height or 0)
end
local function OnWidthSet(self, width)
local content = self.content
content:SetWidth(width)
content.width = width
end
local function OnHeightSet(self, height)
local content = self.content
content:SetHeight(height)
content.height = height
end
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = Type
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.frame = frame
self.LayoutFinished = LayoutFinished
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
frame.obj = self
frame:SetHeight(100)
frame:SetWidth(100)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
--Container Support
local content = CreateFrame("Frame",nil,frame)
self.content = content
content.obj = self
content:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
content:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
AceGUI:RegisterAsContainer(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
+281 -282
View File
@@ -1,282 +1,281 @@
local AceGUI = LibStub("AceGUI-3.0") --[[-----------------------------------------------------------------------------
Slider Widget
-- Lua APIs Graphical Slider, like, for Range values.
local min, max, floor = math.min, math.max, math.floor -------------------------------------------------------------------------------]]
local tonumber = tonumber local Type, Version = "Slider", 24
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
-- WoW APIs if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
local CreateFrame, UIParent = CreateFrame, UIParent
-- Lua APIs
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded local min, max, floor = math.min, math.max, math.floor
-- List them here for Mikk's FindGlobals script local tonumber, pairs = tonumber, pairs
-- GLOBALS: GameFontHighlightSmall
-- WoW APIs
-------------------------- local PlaySound = PlaySound
-- Slider -- local CreateFrame, UIParent = CreateFrame, UIParent
--------------------------
do --[[-----------------------------------------------------------------------------
local Type = "Slider" Support functions
local Version = 9 -------------------------------------------------------------------------------]]
local function UpdateText(self)
local function OnAcquire(self) local value = self.value or 0
self:SetWidth(200) if self.ispercent then
self:SetHeight(44) self.editbox:SetText(("%s%%"):format(floor(value * 1000 + 0.5) / 10))
self:SetDisabled(false) else
self:SetIsPercent(nil) self.editbox:SetText(floor(value * 100 + 0.5) / 100)
self:SetSliderValues(0,100,1) end
self:SetValue(0) end
end
local function UpdateLabels(self)
local function OnRelease(self) local min_value, max_value = (self.min or 0), (self.max or 100)
self.frame:ClearAllPoints() if self.ispercent then
self.frame:Hide() self.lowtext:SetFormattedText("%s%%", (min_value * 100))
self.slider:EnableMouseWheel(false) self.hightext:SetFormattedText("%s%%", (max_value * 100))
self:SetDisabled(false) else
end self.lowtext:SetText(min_value)
self.hightext:SetText(max_value)
local function Control_OnEnter(this) end
this.obj:Fire("OnEnter") end
end
--[[-----------------------------------------------------------------------------
local function Control_OnLeave(this) Scripts
this.obj:Fire("OnLeave") -------------------------------------------------------------------------------]]
end local function Control_OnEnter(frame)
frame.obj:Fire("OnEnter")
local function UpdateText(self) end
local value = self.value or 0
if self.ispercent then local function Control_OnLeave(frame)
self.editbox:SetText(("%s%%"):format(floor(value*1000+0.5)/10)) frame.obj:Fire("OnLeave")
else end
self.editbox:SetText(floor(value*100+0.5)/100)
end local function Frame_OnMouseDown(frame)
end frame.obj.slider:EnableMouseWheel(true)
AceGUI:ClearFocus()
local function UpdateLabels(self) end
local min, max = (self.min or 0), (self.max or 100)
if self.ispercent then local function Slider_OnValueChanged(frame, newvalue)
self.lowtext:SetFormattedText("%s%%",(min * 100)) local self = frame.obj
self.hightext:SetFormattedText("%s%%",(max * 100)) if not frame.setup then
else if self.step and self.step > 0 then
self.lowtext:SetText(min) local min_value = self.min or 0
self.hightext:SetText(max) newvalue = floor((newvalue - min_value) / self.step + 0.5) * self.step + min_value
end end
end if newvalue ~= self.value and not self.disabled then
self.value = newvalue
local function Slider_OnValueChanged(this) self:Fire("OnValueChanged", newvalue)
local self = this.obj end
if not this.setup then if self.value then
local newvalue UpdateText(self)
newvalue = this:GetValue() end
if newvalue ~= self.value and not self.disabled then end
self.value = newvalue end
self:Fire("OnValueChanged", newvalue)
end local function Slider_OnMouseUp(frame)
if self.value then local self = frame.obj
local value = self.value self:Fire("OnMouseUp", self.value)
UpdateText(self) end
end
end local function Slider_OnMouseWheel(frame, v)
end local self = frame.obj
if not self.disabled then
local function Slider_OnMouseUp(this) local value = self.value
local self = this.obj if v > 0 then
self:Fire("OnMouseUp",this:GetValue()) value = min(value + (self.step or 1), self.max)
end else
value = max(value - (self.step or 1), self.min)
local function Slider_OnMouseWheel(this, v) end
local self = this.obj self.slider:SetValue(value)
if not self.disabled then end
local value = self.value end
if v > 0 then
value = min(value + (self.step or 1),self.max) local function EditBox_OnEscapePressed(frame)
else frame:ClearFocus()
value = max(value - (self.step or 1), self.min) end
end
self.slider:SetValue(value) local function EditBox_OnEnterPressed(frame)
end local self = frame.obj
end local value = frame:GetText()
if self.ispercent then
local function SetDisabled(self, disabled) value = value:gsub('%%', '')
self.disabled = disabled value = tonumber(value) / 100
if disabled then else
self.slider:EnableMouse(false) value = tonumber(value)
self.label:SetTextColor(.5,.5,.5) end
self.hightext:SetTextColor(.5,.5,.5)
self.lowtext:SetTextColor(.5,.5,.5) if value then
--self.valuetext:SetTextColor(.5,.5,.5) PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
self.editbox:SetTextColor(.5,.5,.5) self.slider:SetValue(value)
self.editbox:EnableMouse(false) self:Fire("OnMouseUp", value)
self.editbox:ClearFocus() end
else end
self.slider:EnableMouse(true)
self.label:SetTextColor(1,.82,0) local function EditBox_OnEnter(frame)
self.hightext:SetTextColor(1,1,1) frame:SetBackdropBorderColor(0.5, 0.5, 0.5, 1)
self.lowtext:SetTextColor(1,1,1) end
--self.valuetext:SetTextColor(1,1,1)
self.editbox:SetTextColor(1,1,1) local function EditBox_OnLeave(frame)
self.editbox:EnableMouse(true) frame:SetBackdropBorderColor(0.3, 0.3, 0.3, 0.8)
end end
end
--[[-----------------------------------------------------------------------------
local function SetValue(self, value) Methods
self.slider.setup = true -------------------------------------------------------------------------------]]
self.slider:SetValue(value) local methods = {
self.value = value ["OnAcquire"] = function(self)
UpdateText(self) self:SetWidth(200)
self.slider.setup = nil self:SetHeight(44)
end self:SetDisabled(false)
self:SetIsPercent(nil)
local function SetLabel(self, text) self:SetSliderValues(0,100,1)
self.label:SetText(text) self:SetValue(0)
end self.slider:EnableMouseWheel(false)
end,
local function SetSliderValues(self, min, max, step)
local frame = self.slider -- ["OnRelease"] = nil,
frame.setup = true
self.min = min ["SetDisabled"] = function(self, disabled)
self.max = max self.disabled = disabled
self.step = step if disabled then
frame:SetMinMaxValues(min or 0,max or 100) self.slider:EnableMouse(false)
UpdateLabels(self) self.label:SetTextColor(.5, .5, .5)
frame:SetValueStep(step or 1) self.hightext:SetTextColor(.5, .5, .5)
if self.value then self.lowtext:SetTextColor(.5, .5, .5)
frame:SetValue(self.value) --self.valuetext:SetTextColor(.5, .5, .5)
end self.editbox:SetTextColor(.5, .5, .5)
frame.setup = nil self.editbox:EnableMouse(false)
end self.editbox:ClearFocus()
else
local function EditBox_OnEscapePressed(this) self.slider:EnableMouse(true)
this:ClearFocus() self.label:SetTextColor(1, .82, 0)
end self.hightext:SetTextColor(1, 1, 1)
self.lowtext:SetTextColor(1, 1, 1)
local function EditBox_OnEnterPressed(this) --self.valuetext:SetTextColor(1, 1, 1)
local self = this.obj self.editbox:SetTextColor(1, 1, 1)
local value = this:GetText() self.editbox:EnableMouse(true)
if self.ispercent then end
value = value:gsub('%%','') end,
value = tonumber(value) / 100
else ["SetValue"] = function(self, value)
value = tonumber(value) self.slider.setup = true
end self.slider:SetValue(value)
self.value = value
if value then UpdateText(self)
self:Fire("OnMouseUp",value) self.slider.setup = nil
end end,
end
["GetValue"] = function(self)
local function EditBox_OnEnter(this) return self.value
this:SetBackdropBorderColor(0.5,0.5,0.5,1) end,
end
["SetLabel"] = function(self, text)
local function EditBox_OnLeave(this) self.label:SetText(text)
this:SetBackdropBorderColor(0.3,0.3,0.3,0.8) end,
end
["SetSliderValues"] = function(self, min_value, max_value, step)
local function SetIsPercent(self, value) local frame = self.slider
self.ispercent = value frame.setup = true
UpdateLabels(self) self.min = min_value
UpdateText(self) self.max = max_value
end self.step = step
frame:SetMinMaxValues(min_value or 0,max_value or 100)
local function FrameOnMouseDown(this) UpdateLabels(self)
this.obj.slider:EnableMouseWheel(true) frame:SetValueStep(step or 1)
AceGUI:ClearFocus() if self.value then
end frame:SetValue(self.value)
end
local SliderBackdrop = { frame.setup = nil
bgFile = "Interface\\Buttons\\UI-SliderBar-Background", end,
edgeFile = "Interface\\Buttons\\UI-SliderBar-Border",
tile = true, tileSize = 8, edgeSize = 8, ["SetIsPercent"] = function(self, value)
insets = { left = 3, right = 3, top = 6, bottom = 6 } self.ispercent = value
} UpdateLabels(self)
UpdateText(self)
local ManualBackdrop = { end
bgFile = "Interface\\ChatFrame\\ChatFrameBackground", }
edgeFile = "Interface\\ChatFrame\\ChatFrameBackground",
tile = true, edgeSize = 1, tileSize = 5, --[[-----------------------------------------------------------------------------
} Constructor
-------------------------------------------------------------------------------]]
local function Constructor() local SliderBackdrop = {
local frame = CreateFrame("Frame",nil,UIParent) bgFile = "Interface\\Buttons\\UI-SliderBar-Background",
local self = {} edgeFile = "Interface\\Buttons\\UI-SliderBar-Border",
self.type = Type tile = true, tileSize = 8, edgeSize = 8,
insets = { left = 3, right = 3, top = 6, bottom = 6 }
self.OnRelease = OnRelease }
self.OnAcquire = OnAcquire
local ManualBackdrop = {
self.frame = frame bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
frame.obj = self edgeFile = "Interface\\ChatFrame\\ChatFrameBackground",
tile = true, edgeSize = 1, tileSize = 5,
self.SetDisabled = SetDisabled }
self.SetValue = SetValue
self.SetSliderValues = SetSliderValues local function Constructor()
self.SetLabel = SetLabel local frame = CreateFrame("Frame", nil, UIParent)
self.SetIsPercent = SetIsPercent
frame:EnableMouse(true)
self.alignoffset = 25 frame:SetScript("OnMouseDown", Frame_OnMouseDown)
frame:EnableMouse(true) local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
frame:SetScript("OnMouseDown",FrameOnMouseDown) label:SetPoint("TOPLEFT")
self.slider = CreateFrame("Slider",nil,frame) label:SetPoint("TOPRIGHT")
local slider = self.slider label:SetJustifyH("CENTER")
slider:SetScript("OnEnter",Control_OnEnter) label:SetHeight(15)
slider:SetScript("OnLeave",Control_OnLeave)
slider:SetScript("OnMouseUp", Slider_OnMouseUp) local slider = CreateFrame("Slider", nil, frame, "BackdropTemplate")
slider.obj = self slider:SetOrientation("HORIZONTAL")
slider:SetOrientation("HORIZONTAL") slider:SetHeight(15)
slider:SetHeight(15) slider:SetHitRectInsets(0, 0, -10, 0)
slider:SetHitRectInsets(0,0,-10,0) slider:SetBackdrop(SliderBackdrop)
slider:SetBackdrop(SliderBackdrop) slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Horizontal")
--slider:EnableMouseWheel(true) slider:SetPoint("TOP", label, "BOTTOM")
slider:SetScript("OnMouseWheel", Slider_OnMouseWheel) slider:SetPoint("LEFT", 3, 0)
slider:SetPoint("RIGHT", -3, 0)
local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormal") slider:SetValue(0)
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0) slider:SetScript("OnValueChanged",Slider_OnValueChanged)
label:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0) slider:SetScript("OnEnter", Control_OnEnter)
label:SetJustifyH("CENTER") slider:SetScript("OnLeave", Control_OnLeave)
label:SetHeight(15) slider:SetScript("OnMouseUp", Slider_OnMouseUp)
self.label = label slider:SetScript("OnMouseWheel", Slider_OnMouseWheel)
self.lowtext = slider:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall") local lowtext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
self.lowtext:SetPoint("TOPLEFT",slider,"BOTTOMLEFT",2,3) lowtext:SetPoint("TOPLEFT", slider, "BOTTOMLEFT", 2, 3)
self.hightext = slider:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall") local hightext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
self.hightext:SetPoint("TOPRIGHT",slider,"BOTTOMRIGHT",-2,3) hightext:SetPoint("TOPRIGHT", slider, "BOTTOMRIGHT", -2, 3)
local editbox = CreateFrame("EditBox", nil, frame, "BackdropTemplate")
local editbox = CreateFrame("EditBox",nil,frame) editbox:SetAutoFocus(false)
editbox:SetAutoFocus(false) editbox:SetFontObject(GameFontHighlightSmall)
editbox:SetFontObject(GameFontHighlightSmall) editbox:SetPoint("TOP", slider, "BOTTOM")
editbox:SetPoint("TOP",slider,"BOTTOM",0,0) editbox:SetHeight(14)
editbox:SetHeight(14) editbox:SetWidth(70)
editbox:SetWidth(70) editbox:SetJustifyH("CENTER")
editbox:SetJustifyH("CENTER") editbox:EnableMouse(true)
editbox:EnableMouse(true) editbox:SetBackdrop(ManualBackdrop)
editbox:SetScript("OnEscapePressed",EditBox_OnEscapePressed) editbox:SetBackdropColor(0, 0, 0, 0.5)
editbox:SetScript("OnEnterPressed",EditBox_OnEnterPressed) editbox:SetBackdropBorderColor(0.3, 0.3, 0.30, 0.80)
editbox:SetScript("OnEnter",EditBox_OnEnter) editbox:SetScript("OnEnter", EditBox_OnEnter)
editbox:SetScript("OnLeave",EditBox_OnLeave) editbox:SetScript("OnLeave", EditBox_OnLeave)
editbox:SetBackdrop(ManualBackdrop) editbox:SetScript("OnEnterPressed", EditBox_OnEnterPressed)
editbox:SetBackdropColor(0,0,0,0.5) editbox:SetScript("OnEscapePressed", EditBox_OnEscapePressed)
editbox:SetBackdropBorderColor(0.3,0.3,0.30,0.80)
self.editbox = editbox local widget = {
editbox.obj = self label = label,
slider = slider,
slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Horizontal") lowtext = lowtext,
hightext = hightext,
frame:SetWidth(200) editbox = editbox,
frame:SetHeight(44) alignoffset = 25,
slider:SetPoint("TOP",label,"BOTTOM",0,0) frame = frame,
slider:SetPoint("LEFT",frame,"LEFT",3,0) type = Type
slider:SetPoint("RIGHT",frame,"RIGHT",-3,0) }
for method, func in pairs(methods) do
widget[method] = func
slider:SetValue(self.value or 0) end
slider:SetScript("OnValueChanged",Slider_OnValueChanged) slider.obj, editbox.obj = widget, widget
C_Timer.After(0.3, function() editbox:SetText(" ") UpdateText(widget) end) -- Workaround for font loading issue, making the editboxes blank until the text is changed
AceGUI:RegisterAsWidget(self)
return self return AceGUI:RegisterAsWidget(widget)
end end
AceGUI:RegisterWidgetType(Type,Constructor,Version) AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
@@ -1,387 +0,0 @@
local AceGUI = LibStub("AceGUI-3.0")
-- Lua APIs
local pairs, ipairs, assert, type = pairs, ipairs, assert, type
-- WoW APIs
local CreateFrame, UIParent = CreateFrame, UIParent
local _G = _G
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: PanelTemplates_TabResize, PanelTemplates_SetDisabledTabState, PanelTemplates_SelectTab, PanelTemplates_DeselectTab
-------------
-- Widgets --
-------------
--[[
Widgets must provide the following functions
Acquire() - Called when the object is aquired, should set everything to a default hidden state
Release() - Called when the object is Released, should remove any anchors and hide the Widget
And the following members
frame - the frame or derivitive object that will be treated as the widget for size and anchoring purposes
type - the type of the object, same as the name given to :RegisterWidget()
Widgets contain a table called userdata, this is a safe place to store data associated with the wigdet
It will be cleared automatically when a widget is released
Placing values directly into a widget object should be avoided
If the Widget can act as a container for other Widgets the following
content - frame or derivitive that children will be anchored to
The Widget can supply the following Optional Members
]]
--------------------------
-- Tab Group --
--------------------------
do
local Type = "TabGroup"
local Version = 24
local PaneBackdrop = {
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 16,
insets = { left = 3, right = 3, top = 5, bottom = 3 }
}
local function OnAcquire(self)
end
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
self.status = nil
for k in pairs(self.localstatus) do
self.localstatus[k] = nil
end
self.tablist = nil
for _, tab in pairs(self.tabs) do
tab:Hide()
end
self:SetTitle()
end
local function Tab_SetText(self, text)
self:_SetText(text)
local width = self.obj.frame.width or self.obj.frame:GetWidth() or 0
PanelTemplates_TabResize(self, 0, nil, width)
end
local function UpdateTabLook(self)
if self.disabled then
PanelTemplates_SetDisabledTabState(self)
elseif self.selected then
PanelTemplates_SelectTab(self)
else
PanelTemplates_DeselectTab(self)
end
end
local function Tab_SetSelected(self, selected)
self.selected = selected
UpdateTabLook(self)
end
local function Tab_OnClick(self)
if not (self.selected or self.disabled) then
self.obj:SelectTab(self.value)
end
end
local function Tab_SetDisabled(self, disabled)
self.disabled = disabled
UpdateTabLook(self)
end
local function Tab_OnEnter(this)
local self = this.obj
self:Fire("OnTabEnter", self.tabs[this.id].value, this)
end
local function Tab_OnLeave(this)
local self = this.obj
self:Fire("OnTabLeave", self.tabs[this.id].value, this)
end
local function Tab_OnShow(this)
_G[this:GetName().."HighlightTexture"]:SetWidth(this:GetTextWidth() + 30)
end
local function CreateTab(self, id)
local tabname = "AceGUITabGroup"..self.num.."Tab"..id
local tab = CreateFrame("Button",tabname,self.border,"OptionsFrameTabButtonTemplate")
tab.obj = self
tab.id = id
tab.text = _G[tabname .. "Text"]
tab.text:ClearAllPoints()
tab.text:SetPoint("LEFT", tab, "LEFT", 14, -3)
tab.text:SetPoint("RIGHT", tab, "RIGHT", -12, -3)
tab:SetScript("OnClick",Tab_OnClick)
tab:SetScript("OnEnter",Tab_OnEnter)
tab:SetScript("OnLeave",Tab_OnLeave)
tab:SetScript("OnShow", Tab_OnShow)
tab._SetText = tab.SetText
tab.SetText = Tab_SetText
tab.SetSelected = Tab_SetSelected
tab.SetDisabled = Tab_SetDisabled
return tab
end
local function SetTitle(self, text)
self.titletext:SetText(text or "")
if text and text ~= "" then
self.alignoffset = 25
else
self.alignoffset = 18
end
self:BuildTabs()
end
-- called to set an external table to store status in
local function SetStatusTable(self, status)
assert(type(status) == "table")
self.status = status
end
local function SelectTab(self, value)
local status = self.status or self.localstatus
local found
for i, v in ipairs(self.tabs) do
if v.value == value then
v:SetSelected(true)
found = true
else
v:SetSelected(false)
end
end
status.selected = value
if found then
self:Fire("OnGroupSelected",value)
end
end
local function SetTabs(self, tabs)
self.tablist = tabs
self:BuildTabs()
end
local widths = {}
local rowwidths = {}
local rowends = {}
local function BuildTabs(self)
local hastitle = (self.titletext:GetText() and self.titletext:GetText() ~= "")
local status = self.status or self.localstatus
local tablist = self.tablist
local tabs = self.tabs
if not tablist then return end
local width = self.frame.width or self.frame:GetWidth() or 0
for i = #widths, 1, -1 do
widths[i] = nil
end
for i = #rowwidths, 1, -1 do
rowwidths[i] = nil
end
for i = #rowends, 1, -1 do
rowends[i] = nil
end
--Place Text into tabs and get thier initial width
for i, v in ipairs(tablist) do
local tab = tabs[i]
if not tab then
tab = self:CreateTab(i)
tabs[i] = tab
end
tab:Show()
tab:SetText(v.text)
tab:SetDisabled(v.disabled)
tab.value = v.value
widths[i] = tab:GetWidth() - 6 --tabs are anchored 10 pixels from the right side of the previous one to reduce spacing, but add a fixed 4px padding for the text
end
for i = (#tablist)+1, #tabs, 1 do
tabs[i]:Hide()
end
--First pass, find the minimum number of rows needed to hold all tabs and the initial tab layout
local numtabs = #tablist
local numrows = 1
local usedwidth = 0
for i = 1, #tablist do
--If this is not the first tab of a row and there isn't room for it
if usedwidth ~= 0 and (width - usedwidth - widths[i]) < 0 then
rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
rowends[numrows] = i - 1
numrows = numrows + 1
usedwidth = 0
end
usedwidth = usedwidth + widths[i]
end
rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
rowends[numrows] = #tablist
--Fix for single tabs being left on the last row, move a tab from the row above if applicable
if numrows > 1 then
--if the last row has only one tab
if rowends[numrows-1] == numtabs-1 then
--if there are more than 2 tabs in the 2nd last row
if (numrows == 2 and rowends[numrows-1] > 2) or (rowends[numrows] - rowends[numrows-1] > 2) then
--move 1 tab from the second last row to the last, if there is enough space
if (rowwidths[numrows] + widths[numtabs-1]) <= width then
rowends[numrows-1] = rowends[numrows-1] - 1
rowwidths[numrows] = rowwidths[numrows] + widths[numtabs-1]
rowwidths[numrows-1] = rowwidths[numrows-1] - widths[numtabs-1]
end
end
end
end
--anchor the rows as defined and resize tabs to fill thier row
local starttab = 1
for row, endtab in ipairs(rowends) do
local first = true
for tabno = starttab, endtab do
local tab = tabs[tabno]
tab:ClearAllPoints()
if first then
tab:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 0, -(hastitle and 14 or 7)-(row-1)*20 )
first = false
else
tab:SetPoint("LEFT", tabs[tabno-1], "RIGHT", -10, 0)
end
end
-- equal padding for each tab to fill the available width,
-- if the used space is above 75% already
local padding = 0
if not (numrows == 1 and rowwidths[1] < width*0.75) then
padding = (width - rowwidths[row]) / (endtab - starttab+1)
end
for i = starttab, endtab do
PanelTemplates_TabResize(tabs[i], padding + 4, nil, width)
end
starttab = endtab + 1
end
self.borderoffset = (hastitle and 17 or 10)+((numrows)*20)
self.border:SetPoint("TOPLEFT",self.frame,"TOPLEFT",1,-self.borderoffset)
end
local function BuildTabsOnUpdate(this)
BuildTabs(this.obj)
this:SetScript("OnUpdate", nil)
end
local function OnWidthSet(self, width)
local content = self.content
local contentwidth = width - 60
if contentwidth < 0 then
contentwidth = 0
end
content:SetWidth(contentwidth)
content.width = contentwidth
BuildTabs(self)
self.frame:SetScript("OnUpdate", BuildTabsOnUpdate)
end
local function OnHeightSet(self, height)
local content = self.content
local contentheight = height - (self.borderoffset + 23)
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end
local function LayoutFinished(self, width, height)
if self.noAutoHeight then return end
self:SetHeight((height or 0) + (self.borderoffset + 23))
end
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = Type
self.num = AceGUI:GetNextWidgetNum(Type)
self.localstatus = {}
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.SetTitle = SetTitle
self.CreateTab = CreateTab
self.SelectTab = SelectTab
self.BuildTabs = BuildTabs
self.SetStatusTable = SetStatusTable
self.SetTabs = SetTabs
self.LayoutFinished = LayoutFinished
self.frame = frame
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
frame.obj = self
frame:SetHeight(100)
frame:SetWidth(100)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
self.alignoffset = 18
local titletext = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
titletext:SetPoint("TOPLEFT",frame,"TOPLEFT",14,0)
titletext:SetPoint("TOPRIGHT",frame,"TOPRIGHT",-14,0)
titletext:SetJustifyH("LEFT")
titletext:SetHeight(18)
titletext:SetText("")
self.titletext = titletext
local border = CreateFrame("Frame",nil,frame)
self.border = border
self.borderoffset = 27
border:SetPoint("TOPLEFT",frame,"TOPLEFT",1,-27)
border:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-1,3)
border:SetBackdrop(PaneBackdrop)
border:SetBackdropColor(0.1,0.1,0.1,0.5)
border:SetBackdropBorderColor(0.4,0.4,0.4)
self.tabs = {}
--Container Support
local content = CreateFrame("Frame",nil,border)
self.content = content
content.obj = self
content:SetPoint("TOPLEFT",border,"TOPLEFT",10,-7)
content:SetPoint("BOTTOMRIGHT",border,"BOTTOMRIGHT",-10,7)
AceGUI:RegisterAsContainer(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
@@ -1,746 +0,0 @@
local AceGUI = LibStub("AceGUI-3.0")
-- Lua APIs
local next, pairs, ipairs, assert, type = next, pairs, ipairs, assert, type
local math_min, math_max, floor = math.min, math.max, floor
local select, tremove, unpack = select, table.remove, unpack
-- WoW APIs
local CreateFrame, UIParent = CreateFrame, UIParent
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: GameTooltip, FONT_COLOR_CODE_CLOSE
-- Recycling functions
local new, del
do
local pool = setmetatable({},{__mode='k'})
function new()
local t = next(pool)
if t then
pool[t] = nil
return t
else
return {}
end
end
function del(t)
for k in pairs(t) do
t[k] = nil
end
pool[t] = true
end
end
--------------
-- TreeView --
--------------
do
local Type = "TreeGroup"
local Version = 23
local DEFAULT_TREE_WIDTH = 175
local DEFAULT_TREE_SIZABLE = true
local PaneBackdrop = {
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 16,
insets = { left = 3, right = 3, top = 5, bottom = 3 }
}
local DraggerBackdrop = {
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
edgeFile = nil,
tile = true, tileSize = 16, edgeSize = 0,
insets = { left = 3, right = 3, top = 7, bottom = 7 }
}
local function OnAcquire(self)
self:SetTreeWidth(DEFAULT_TREE_WIDTH,DEFAULT_TREE_SIZABLE)
self:EnableButtonTooltips(true)
end
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
self.status = nil
for k, v in pairs(self.localstatus) do
if k == "groups" then
for k2 in pairs(v) do
v[k2] = nil
end
else
self.localstatus[k] = nil
end
end
self.localstatus.scrollvalue = 0
self.localstatus.treewidth = DEFAULT_TREE_WIDTH
self.localstatus.treesizable = DEFAULT_TREE_SIZABLE
end
local function GetButtonParents(line)
local parent = line.parent
if parent and parent.value then
return parent.value, GetButtonParents(parent)
end
end
local function GetButtonUniqueValue(line)
local parent = line.parent
if parent and parent.value then
return GetButtonUniqueValue(parent).."\001"..line.value
else
return line.value
end
end
local function ButtonOnClick(this)
local self = this.obj
self:Fire("OnClick",this.uniquevalue, this.selected)
if not this.selected then
self:SetSelected(this.uniquevalue)
this.selected = true
this:LockHighlight()
self:RefreshTree()
end
AceGUI:ClearFocus()
end
local function ExpandOnClick(this)
local button = this.button
local self = button.obj
local status = (self.status or self.localstatus).groups
status[button.uniquevalue] = not status[button.uniquevalue]
self:RefreshTree()
end
local function ButtonOnDoubleClick(button)
local self = button.obj
local status = self.status or self.localstatus
local status = (self.status or self.localstatus).groups
status[button.uniquevalue] = not status[button.uniquevalue]
self:RefreshTree()
end
local function EnableButtonTooltips(self, enable)
self.enabletooltips = enable
end
local function Button_OnEnter(this)
local self = this.obj
self:Fire("OnButtonEnter", this.uniquevalue, this)
if self.enabletooltips then
GameTooltip:SetOwner(this, "ANCHOR_NONE")
GameTooltip:SetPoint("LEFT",this,"RIGHT")
GameTooltip:SetText(this.text:GetText() or "", 1, .82, 0, 1)
GameTooltip:Show()
end
end
local function Button_OnLeave(this)
local self = this.obj
self:Fire("OnButtonLeave", this.uniquevalue, this)
if self.enabletooltips then
GameTooltip:Hide()
end
end
local buttoncount = 1
local function CreateButton(self)
local button = CreateFrame("Button",("AceGUI30TreeButton%d"):format(buttoncount),self.treeframe, "OptionsListButtonTemplate")
buttoncount = buttoncount + 1
button.obj = self
local icon = button:CreateTexture(nil, "OVERLAY")
icon:SetWidth(14)
icon:SetHeight(14)
button.icon = icon
button:SetScript("OnClick",ButtonOnClick)
button:SetScript("OnDoubleClick", ButtonOnDoubleClick)
button:SetScript("OnEnter",Button_OnEnter)
button:SetScript("OnLeave",Button_OnLeave)
button.toggle.button = button
button.toggle:SetScript("OnClick",ExpandOnClick)
return button
end
local function UpdateButton(button, treeline, selected, canExpand, isExpanded)
local self = button.obj
local toggle = button.toggle
local frame = self.frame
local text = treeline.text or ""
local icon = treeline.icon
local iconCoords = treeline.iconCoords
local level = treeline.level
local value = treeline.value
local uniquevalue = treeline.uniquevalue
local disabled = treeline.disabled
button.treeline = treeline
button.value = value
button.uniquevalue = uniquevalue
if selected then
button:LockHighlight()
button.selected = true
else
button:UnlockHighlight()
button.selected = false
end
local normalTexture = button:GetNormalTexture()
local line = button.line
button.level = level
if ( level == 1 ) then
button:SetNormalFontObject("GameFontNormal")
button:SetHighlightFontObject("GameFontHighlight")
button.text:SetPoint("LEFT", (icon and 16 or 0) + 8, 2)
else
button:SetNormalFontObject("GameFontHighlightSmall")
button:SetHighlightFontObject("GameFontHighlightSmall")
button.text:SetPoint("LEFT", (icon and 16 or 0) + 8 * level, 2)
end
if disabled then
button:EnableMouse(false)
button.text:SetText("|cff808080"..text..FONT_COLOR_CODE_CLOSE)
else
button.text:SetText(text)
button:EnableMouse(true)
end
if icon then
button.icon:SetTexture(icon)
button.icon:SetPoint("LEFT", button, "LEFT", 8 * level, (level == 1) and 0 or 1)
else
button.icon:SetTexture(nil)
end
if iconCoords then
button.icon:SetTexCoord(unpack(iconCoords))
else
button.icon:SetTexCoord(0, 1, 0, 1)
end
if canExpand then
if not isExpanded then
toggle:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-UP")
toggle:SetPushedTexture("Interface\\Buttons\\UI-PlusButton-DOWN")
else
toggle:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-UP")
toggle:SetPushedTexture("Interface\\Buttons\\UI-MinusButton-DOWN")
end
toggle:Show()
else
toggle:Hide()
end
end
local function OnScrollValueChanged(this, value)
if this.obj.noupdate then return end
local self = this.obj
local status = self.status or self.localstatus
status.scrollvalue = value
self:RefreshTree()
AceGUI:ClearFocus()
end
-- called to set an external table to store status in
local function SetStatusTable(self, status)
assert(type(status) == "table")
self.status = status
if not status.groups then
status.groups = {}
end
if not status.scrollvalue then
status.scrollvalue = 0
end
if not status.treewidth then
status.treewidth = DEFAULT_TREE_WIDTH
end
if not status.treesizable then
status.treesizable = DEFAULT_TREE_SIZABLE
end
self:SetTreeWidth(status.treewidth,status.treesizable)
self:RefreshTree()
end
--sets the tree to be displayed
--[[
example tree
Alpha
Bravo
-Charlie
-Delta
-Echo
Foxtrot
tree = {
{
value = "A",
text = "Alpha"
},
{
value = "B",
text = "Bravo",
children = {
{
value = "C",
text = "Charlie"
},
{
value = "D",
text = "Delta"
children = {
{
value = "E",
text = "Echo"
}
}
}
}
},
{
value = "F",
text = "Foxtrot"
},
}
]]
local function SetTree(self, tree, filter)
self.filter = filter
if tree then
assert(type(tree) == "table")
end
self.tree = tree
self:RefreshTree()
end
local function ShouldDisplayLevel(tree)
local result = false
for k, v in ipairs(tree) do
if v.children == nil and v.visible ~= false then
result = true
elseif v.children then
result = result or ShouldDisplayLevel(v.children)
end
if result then return result end
end
return false
end
local function addLine(self, v, tree, level, parent)
local line = new()
line.value = v.value
line.text = v.text
line.icon = v.icon
line.iconCoords = v.iconCoords
line.disabled = v.disabled
line.tree = tree
line.level = level
line.parent = parent
line.visible = v.visible
line.uniquevalue = GetButtonUniqueValue(line)
if v.children then
line.hasChildren = true
else
line.hasChildren = nil
end
self.lines[#self.lines+1] = line
return line
end
local function BuildLevel(self, tree, level, parent)
local groups = (self.status or self.localstatus).groups
local hasChildren = self.hasChildren
for i, v in ipairs(tree) do
if v.children then
if not self.filter or ShouldDisplayLevel(v.children) then
local line = addLine(self, v, tree, level, parent)
if groups[line.uniquevalue] then
self:BuildLevel(v.children, level+1, line)
end
end
elseif v.visible ~= false or not self.filter then
addLine(self, v, tree, level, parent)
end
end
end
--fire an update after one frame to catch the treeframes height
local function FirstFrameUpdate(this)
local self = this.obj
this:SetScript("OnUpdate",nil)
self:RefreshTree()
end
local function ResizeUpdate(this)
this.obj:RefreshTree()
end
local function RefreshTree(self)
local buttons = self.buttons
local lines = self.lines
for i, v in ipairs(buttons) do
v:Hide()
end
while lines[1] do
local t = tremove(lines)
for k in pairs(t) do
t[k] = nil
end
del(t)
end
if not self.tree then return end
--Build the list of visible entries from the tree and status tables
local status = self.status or self.localstatus
local groupstatus = status.groups
local tree = self.tree
local treeframe = self.treeframe
self:BuildLevel(tree, 1)
local numlines = #lines
local maxlines = (floor(((self.treeframe:GetHeight()or 0) - 20 ) / 18))
local first, last
if numlines <= maxlines then
--the whole tree fits in the frame
status.scrollvalue = 0
self:ShowScroll(false)
first, last = 1, numlines
else
self:ShowScroll(true)
--scrolling will be needed
self.noupdate = true
self.scrollbar:SetMinMaxValues(0, numlines - maxlines)
--check if we are scrolled down too far
if numlines - status.scrollvalue < maxlines then
status.scrollvalue = numlines - maxlines
self.scrollbar:SetValue(status.scrollvalue)
end
self.noupdate = nil
first, last = status.scrollvalue+1, status.scrollvalue + maxlines
end
local buttonnum = 1
for i = first, last do
local line = lines[i]
local button = buttons[buttonnum]
if not button then
button = self:CreateButton()
buttons[buttonnum] = button
button:SetParent(treeframe)
button:SetFrameLevel(treeframe:GetFrameLevel()+1)
button:ClearAllPoints()
if i == 1 then
if self.showscroll then
button:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",-22,-10)
button:SetPoint("TOPLEFT", self.treeframe, "TOPLEFT", 0, -10)
else
button:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",0,-10)
button:SetPoint("TOPLEFT", self.treeframe, "TOPLEFT", 0, -10)
end
else
button:SetPoint("TOPRIGHT", buttons[buttonnum-1], "BOTTOMRIGHT",0,0)
button:SetPoint("TOPLEFT", buttons[buttonnum-1], "BOTTOMLEFT",0,0)
end
end
UpdateButton(button, line, status.selected == line.uniquevalue, line.hasChildren, groupstatus[line.uniquevalue] )
button:Show()
buttonnum = buttonnum + 1
end
end
local function SetSelected(self, value)
local status = self.status or self.localstatus
if status.selected ~= value then
status.selected = value
self:Fire("OnGroupSelected", value)
end
end
local function BuildUniqueValue(...)
local n = select('#', ...)
if n == 1 then
return ...
else
return (...).."\001"..BuildUniqueValue(select(2,...))
end
end
local function Select(self, uniquevalue, ...)
self.filter = false
local status = self.status or self.localstatus
local groups = status.groups
for i = 1, select('#', ...) do
groups[BuildUniqueValue(select(i, ...))] = true
end
status.selected = uniquevalue
self:RefreshTree()
self:Fire("OnGroupSelected", uniquevalue)
end
local function SelectByPath(self, ...)
self:Select(BuildUniqueValue(...), ...)
end
--Selects a tree node by UniqueValue
local function SelectByValue(self, uniquevalue)
self:Select(uniquevalue, ("\001"):split(uniquevalue))
end
local function ShowScroll(self, show)
self.showscroll = show
if show then
self.scrollbar:Show()
if self.buttons[1] then
self.buttons[1]:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",-22,-10)
end
else
self.scrollbar:Hide()
if self.buttons[1] then
self.buttons[1]:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",0,-10)
end
end
end
local function OnWidthSet(self, width)
local content = self.content
local treeframe = self.treeframe
local status = self.status or self.localstatus
status.fullwidth = width
local contentwidth = width - status.treewidth - 20
if contentwidth < 0 then
contentwidth = 0
end
content:SetWidth(contentwidth)
content.width = contentwidth
local maxtreewidth = math_min(400, width - 50)
if maxtreewidth > 100 and status.treewidth > maxtreewidth then
self:SetTreeWidth(maxtreewidth, status.treesizable)
end
treeframe:SetMaxResize(maxtreewidth,1600)
end
local function OnHeightSet(self, height)
local content = self.content
local contentheight = height - 20
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end
local function TreeOnMouseWheel(this, delta)
local self = this.obj
if self.showscroll then
local scrollbar = self.scrollbar
local min, max = scrollbar:GetMinMaxValues()
local value = scrollbar:GetValue()
local newvalue = math_min(max,math_max(min,value - delta))
if value ~= newvalue then
scrollbar:SetValue(newvalue)
end
end
end
local function SetTreeWidth(self, treewidth, resizable)
if not resizable then
if type(treewidth) == 'number' then
resizable = false
elseif type(treewidth) == 'boolean' then
resizable = treewidth
treewidth = DEFAULT_TREE_WIDTH
else
resizable = false
treewidth = DEFAULT_TREE_WIDTH
end
end
self.treeframe:SetWidth(treewidth)
self.dragger:EnableMouse(resizable)
local status = self.status or self.localstatus
status.treewidth = treewidth
status.treesizable = resizable
-- recalculate the content width
if status.fullwidth then
self:OnWidthSet(status.fullwidth)
end
end
local function draggerLeave(this)
this:SetBackdropColor(1, 1, 1, 0)
end
local function draggerEnter(this)
this:SetBackdropColor(1, 1, 1, 0.8)
end
local function draggerDown(this)
local treeframe = this:GetParent()
treeframe:StartSizing("RIGHT")
end
local function draggerUp(this)
local treeframe = this:GetParent()
local self = treeframe.obj
local frame = treeframe:GetParent()
treeframe:StopMovingOrSizing()
--treeframe:SetScript("OnUpdate", nil)
treeframe:SetUserPlaced(false)
--Without this :GetHeight will get stuck on the current height, causing the tree contents to not resize
treeframe:SetHeight(0)
treeframe:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
treeframe:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,0)
local status = self.status or self.localstatus
status.treewidth = treeframe:GetWidth()
treeframe.obj:Fire("OnTreeResize",treeframe:GetWidth())
-- recalculate the content width
treeframe.obj:OnWidthSet(status.fullwidth)
-- update the layout of the content
treeframe.obj:DoLayout()
end
local function LayoutFinished(self, width, height)
if self.noAutoHeight then return end
self:SetHeight((height or 0) + 20)
end
local createdcount = 0
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = Type
self.lines = {}
self.levels = {}
self.buttons = {}
self.hasChildren = {}
self.localstatus = {}
self.localstatus.groups = {}
self.filter = false
local treeframe = CreateFrame("Frame",nil,frame)
treeframe.obj = self
treeframe:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
treeframe:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,0)
treeframe:SetWidth(DEFAULT_TREE_WIDTH)
treeframe:SetScript("OnUpdate",FirstFrameUpdate)
treeframe:SetScript("OnSizeChanged",ResizeUpdate)
treeframe:EnableMouseWheel(true)
treeframe:SetScript("OnMouseWheel", TreeOnMouseWheel)
treeframe:SetBackdrop(PaneBackdrop)
treeframe:SetBackdropColor(0.1,0.1,0.1,0.5)
treeframe:SetBackdropBorderColor(0.4,0.4,0.4)
treeframe:SetResizable(true)
treeframe:SetMinResize(100, 1)
treeframe:SetMaxResize(400,1600)
local dragger = CreateFrame("Frame", nil, treeframe)
dragger:SetWidth(8)
dragger:SetPoint("TOP", treeframe, "TOPRIGHT")
dragger:SetPoint("BOTTOM", treeframe, "BOTTOMRIGHT")
dragger:SetBackdrop(DraggerBackdrop)
dragger:SetBackdropColor(1, 1, 1, 0)
dragger:SetScript("OnMouseDown", draggerDown)
dragger:SetScript("OnMouseUp", draggerUp)
dragger:SetScript("OnEnter", draggerEnter)
dragger:SetScript("OnLeave", draggerLeave)
self.dragger = dragger
self.treeframe = treeframe
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.SetTree = SetTree
self.SetTreeWidth = SetTreeWidth
self.RefreshTree = RefreshTree
self.SetStatusTable = SetStatusTable
self.BuildLevel = BuildLevel
self.CreateButton = CreateButton
self.SetSelected = SetSelected
self.ShowScroll = ShowScroll
self.SetStatusTable = SetStatusTable
self.Select = Select
self.SelectByValue = SelectByValue
self.SelectByPath = SelectByPath
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
self.EnableButtonTooltips = EnableButtonTooltips
--self.Filter = Filter
self.LayoutFinished = LayoutFinished
self.frame = frame
frame.obj = self
createdcount = createdcount + 1
local scrollbar = CreateFrame("Slider",("AceConfigDialogTreeGroup%dScrollBar"):format(createdcount),treeframe,"UIPanelScrollBarTemplate")
self.scrollbar = scrollbar
local scrollbg = scrollbar:CreateTexture(nil,"BACKGROUND")
scrollbg:SetAllPoints(scrollbar)
scrollbg:SetTexture(0,0,0,0.4)
scrollbar.obj = self
self.noupdate = true
scrollbar:SetPoint("TOPRIGHT",treeframe,"TOPRIGHT",-10,-26)
scrollbar:SetPoint("BOTTOMRIGHT",treeframe,"BOTTOMRIGHT",-10,26)
scrollbar:SetScript("OnValueChanged", OnScrollValueChanged)
scrollbar:SetMinMaxValues(0,0)
self.localstatus.scrollvalue = 0
scrollbar:SetValueStep(1)
scrollbar:SetValue(0)
scrollbar:SetWidth(16)
self.noupdate = nil
local border = CreateFrame("Frame",nil,frame)
self.border = border
border:SetPoint("TOPLEFT",treeframe,"TOPRIGHT", 0,0)
border:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
border:SetBackdrop(PaneBackdrop)
border:SetBackdropColor(0.1,0.1,0.1,0.5)
border:SetBackdropBorderColor(0.4,0.4,0.4)
--Container Support
local content = CreateFrame("Frame",nil,border)
self.content = content
content.obj = self
content:SetPoint("TOPLEFT",border,"TOPLEFT",10,-10)
content:SetPoint("BOTTOMRIGHT",border,"BOTTOMRIGHT",-10,10)
AceGUI:RegisterAsContainer(self)
--AceGUI:RegisterAsWidget(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
+133 -136
View File
@@ -1,136 +1,133 @@
--- **AceLocale-3.0** manages localization in addons, allowing for multiple locale to be registered with fallback to the base locale for untranslated strings. --- **AceLocale-3.0** manages localization in addons, allowing for multiple locale to be registered with fallback to the base locale for untranslated strings.
-- @class file -- @class file
-- @name AceLocale-3.0 -- @name AceLocale-3.0
-- @release $Id: AceLocale-3.0.lua 895 2009-12-06 16:28:55Z nevcairiel $ -- @release $Id$
local MAJOR,MINOR = "AceLocale-3.0", 2 local MAJOR,MINOR = "AceLocale-3.0", 6
local AceLocale, oldminor = LibStub:NewLibrary(MAJOR, MINOR) local AceLocale, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not AceLocale then return end -- no upgrade needed if not AceLocale then return end -- no upgrade needed
-- Lua APIs -- Lua APIs
local assert, tostring, error = assert, tostring, error local assert, tostring, error = assert, tostring, error
local setmetatable, rawset, rawget = setmetatable, rawset, rawget local getmetatable, setmetatable, rawset, rawget = getmetatable, setmetatable, rawset, rawget
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded local gameLocale = GetLocale()
-- List them here for Mikk's FindGlobals script if gameLocale == "enGB" then
-- GLOBALS: GAME_LOCALE, geterrorhandler gameLocale = "enUS"
end
local gameLocale = GetLocale()
if gameLocale == "enGB" then AceLocale.apps = AceLocale.apps or {} -- array of ["AppName"]=localetableref
gameLocale = "enUS" AceLocale.appnames = AceLocale.appnames or {} -- array of [localetableref]="AppName"
end
-- This metatable is used on all tables returned from GetLocale
AceLocale.apps = AceLocale.apps or {} -- array of ["AppName"]=localetableref local readmeta = {
AceLocale.appnames = AceLocale.appnames or {} -- array of [localetableref]="AppName" __index = function(self, key) -- requesting totally unknown entries: fire off a nonbreaking error and return key
rawset(self, key, key) -- only need to see the warning once, really
-- This metatable is used on all tables returned from GetLocale geterrorhandler()(MAJOR..": "..tostring(AceLocale.appnames[self])..": Missing entry for '"..tostring(key).."'")
local readmeta = { return key
__index = function(self, key) -- requesting totally unknown entries: fire off a nonbreaking error and return key end
rawset(self, key, key) -- only need to see the warning once, really }
geterrorhandler()(MAJOR..": "..tostring(AceLocale.appnames[self])..": Missing entry for '"..tostring(key).."'")
return key -- This metatable is used on all tables returned from GetLocale if the silent flag is true, it does not issue a warning on unknown keys
end local readmetasilent = {
} __index = function(self, key) -- requesting totally unknown entries: return key
rawset(self, key, key) -- only need to invoke this function once
-- This metatable is used on all tables returned from GetLocale if the silent flag is true, it does not issue a warning on unknown keys return key
local readmetasilent = { end
__index = function(self, key) -- requesting totally unknown entries: return key }
rawset(self, key, key) -- only need to invoke this function once
return key -- Remember the locale table being registered right now (it gets set by :NewLocale())
end -- NOTE: Do never try to register 2 locale tables at once and mix their definition.
} local registering
-- Remember the locale table being registered right now (it gets set by :NewLocale()) -- local assert false function
-- NOTE: Do never try to register 2 locale tables at once and mix their definition. local assertfalse = function() assert(false) end
local registering
-- This metatable proxy is used when registering nondefault locales
-- local assert false function local writeproxy = setmetatable({}, {
local assertfalse = function() assert(false) end __newindex = function(self, key, value)
rawset(registering, key, value == true and key or value) -- assigning values: replace 'true' with key string
-- This metatable proxy is used when registering nondefault locales end,
local writeproxy = setmetatable({}, { __index = assertfalse
__newindex = function(self, key, value) })
rawset(registering, key, value == true and key or value) -- assigning values: replace 'true' with key string
end, -- This metatable proxy is used when registering the default locale.
__index = assertfalse -- It refuses to overwrite existing values
}) -- Reason 1: Allows loading locales in any order
-- Reason 2: If 2 modules have the same string, but only the first one to be
-- This metatable proxy is used when registering the default locale. -- loaded has a translation for the current locale, the translation
-- It refuses to overwrite existing values -- doesn't get overwritten.
-- Reason 1: Allows loading locales in any order --
-- Reason 2: If 2 modules have the same string, but only the first one to be local writedefaultproxy = setmetatable({}, {
-- loaded has a translation for the current locale, the translation __newindex = function(self, key, value)
-- doesn't get overwritten. if not rawget(registering, key) then
-- rawset(registering, key, value == true and key or value)
local writedefaultproxy = setmetatable({}, { end
__newindex = function(self, key, value) end,
if not rawget(registering, key) then __index = assertfalse
rawset(registering, key, value == true and key or value) })
end
end, --- Register a new locale (or extend an existing one) for the specified application.
__index = assertfalse -- :NewLocale will return a table you can fill your locale into, or nil if the locale isn't needed for the players
}) -- game locale.
-- @paramsig application, locale[, isDefault[, silent]]
--- Register a new locale (or extend an existing one) for the specified application. -- @param application Unique name of addon / module
-- :NewLocale will return a table you can fill your locale into, or nil if the locale isn't needed for the players -- @param locale Name of the locale to register, e.g. "enUS", "deDE", etc.
-- game locale. -- @param isDefault If this is the default locale being registered (your addon is written in this language, generally enUS)
-- @paramsig application, locale[, isDefault[, silent]] -- @param silent If true, the locale will not issue warnings for missing keys. Must be set on the first locale registered. If set to "raw", nils will be returned for unknown keys (no metatable used).
-- @param application Unique name of addon / module -- @usage
-- @param locale Name of the locale to register, e.g. "enUS", "deDE", etc. -- -- enUS.lua
-- @param isDefault If this is the default locale being registered (your addon is written in this language, generally enUS) -- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "enUS", true)
-- @param silent If true, the locale will not issue warnings for missing keys. Can only be set on the default locale. -- L["string1"] = true
-- @usage --
-- -- enUS.lua -- -- deDE.lua
-- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "enUS", true) -- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "deDE")
-- L["string1"] = true -- if not L then return end
-- -- L["string1"] = "Zeichenkette1"
-- -- deDE.lua -- @return Locale Table to add localizations to, or nil if the current locale is not required.
-- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "deDE") function AceLocale:NewLocale(application, locale, isDefault, silent)
-- if not L then return end
-- L["string1"] = "Zeichenkette1" -- GAME_LOCALE allows translators to test translations of addons without having that wow client installed
-- @return Locale Table to add localizations to, or nil if the current locale is not required. local activeGameLocale = GAME_LOCALE or gameLocale
function AceLocale:NewLocale(application, locale, isDefault, silent)
local app = AceLocale.apps[application]
if silent and not isDefault then
error("Usage: NewLocale(application, locale[, isDefault[, silent]]): 'silent' can only be specified for the default locale", 2) if silent and app and getmetatable(app) ~= readmetasilent then
end geterrorhandler()("Usage: NewLocale(application, locale[, isDefault[, silent]]): 'silent' must be specified for the first locale registered")
end
-- GAME_LOCALE allows translators to test translations of addons without having that wow client installed
-- Ammo: I still think this is a bad idea, for instance an addon that checks for some ingame string will fail, just because some other addon if not app then
-- gives the user the illusion that they can run in a different locale? Ditch this whole thing or allow a setting per 'application'. I'm of the if silent=="raw" then
-- opinion to remove this. app = {}
local gameLocale = GAME_LOCALE or gameLocale else
app = setmetatable({}, silent and readmetasilent or readmeta)
if locale ~= gameLocale and not isDefault then end
return -- nop, we don't need these translations AceLocale.apps[application] = app
end AceLocale.appnames[app] = application
end
local app = AceLocale.apps[application]
if locale ~= activeGameLocale and not isDefault then
if not app then return -- nop, we don't need these translations
app = setmetatable({}, silent and readmetasilent or readmeta) end
AceLocale.apps[application] = app
AceLocale.appnames[app] = application registering = app -- remember globally for writeproxy and writedefaultproxy
end
if isDefault then
registering = app -- remember globally for writeproxy and writedefaultproxy return writedefaultproxy
end
if isDefault then
return writedefaultproxy return writeproxy
end end
return writeproxy --- Returns localizations for the current locale (or default locale if translations are missing).
end -- Errors if nothing is registered (spank developer, not just a missing translation)
-- @param application Unique name of addon / module
--- Returns localizations for the current locale (or default locale if translations are missing). -- @param silent If true, the locale is optional, silently return nil if it's not found (defaults to false, optional)
-- Errors if nothing is registered (spank developer, not just a missing translation) -- @return The locale table for the current language.
-- @param application Unique name of addon / module function AceLocale:GetLocale(application, silent)
-- @param silent If true, the locale is optional, silently return nil if it's not found (defaults to false, optional) if not silent and not AceLocale.apps[application] then
-- @return The locale table for the current language. error("Usage: GetLocale(application[, silent]): 'application' - No locales registered for '"..tostring(application).."'", 2)
function AceLocale:GetLocale(application, silent) end
if not silent and not AceLocale.apps[application] then return AceLocale.apps[application]
error("Usage: GetLocale(application[, silent]): 'application' - No locales registered for '"..tostring(application).."'", 2) end
end
return AceLocale.apps[application]
end
+3 -3
View File
@@ -1,4 +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/ <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"> ..\FrameXML\UI.xsd">
<Script file="AceLocale-3.0.lua"/> <Script file="AceLocale-3.0.lua"/>
</Ui> </Ui>
+278 -473
View File
@@ -1,473 +1,278 @@
--- **AceTimer-3.0** provides a central facility for registering timers. --- **AceTimer-3.0** provides a central facility for registering timers.
-- AceTimer supports one-shot timers and repeating timers. All timers are stored in an efficient -- AceTimer supports one-shot timers and repeating timers. All timers are stored in an efficient
-- data structure that allows easy dispatching and fast rescheduling. Timers can be registered, rescheduled -- data structure that allows easy dispatching and fast rescheduling. Timers can be registered
-- or canceled at any time, even from within a running timer, without conflict or large overhead.\\ -- or canceled at any time, even from within a running timer, without conflict or large overhead.\\
-- AceTimer is currently limited to firing timers at a frequency of 0.1s. This constant may change -- AceTimer is currently limited to firing timers at a frequency of 0.01s as this is what the WoW timer API
-- in the future, but for now it seemed like a good compromise in efficiency and accuracy. -- restricts us to.
-- --
-- All `:Schedule` functions will return a handle to the current timer, which you will need to store if you -- All `:Schedule` functions will return a handle to the current timer, which you will need to store if you
-- need to cancel or reschedule the timer you just registered. -- need to cancel the timer you just registered.
-- --
-- **AceTimer-3.0** can be embeded into your addon, either explicitly by calling AceTimer:Embed(MyAddon) or by -- **AceTimer-3.0** can be embeded into your addon, either explicitly by calling AceTimer:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object -- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceTimer itself.\\ -- and can be accessed directly, without having to explicitly call AceTimer itself.\\
-- It is recommended to embed AceTimer, otherwise you'll have to specify a custom `self` on all calls you -- It is recommended to embed AceTimer, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceTimer. -- make into AceTimer.
-- @class file -- @class file
-- @name AceTimer-3.0 -- @name AceTimer-3.0
-- @release $Id: AceTimer-3.0.lua 895 2009-12-06 16:28:55Z nevcairiel $ -- @release $Id$
--[[ local MAJOR, MINOR = "AceTimer-3.0", 17 -- Bump minor on changes
Basic assumptions: local AceTimer, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
* In a typical system, we do more re-scheduling per second than there are timer pulses per second
* Regardless of timer implementation, we cannot guarantee timely delivery due to FPS restriction (may be as low as 10) if not AceTimer then return end -- No upgrade needed
AceTimer.activeTimers = AceTimer.activeTimers or {} -- Active timer list
This implementation: local activeTimers = AceTimer.activeTimers -- Upvalue our private data
CON: The smallest timer interval is constrained by HZ (currently 1/10s).
PRO: It will still correctly fire any timer slower than HZ over a length of time, e.g. 0.11s interval -> 90 times over 10 seconds -- Lua APIs
PRO: In lag bursts, the system simly skips missed timer intervals to decrease load local type, unpack, next, error, select = type, unpack, next, error, select
CON: Algorithms depending on a timer firing "N times per minute" will fail -- WoW APIs
PRO: (Re-)scheduling is O(1) with a VERY small constant. It's a simple linked list insertion in a hash bucket. local GetTime, C_TimerAfter = GetTime, C_Timer.After
CAUTION: The BUCKETS constant constrains how many timers can be efficiently handled. With too many hash collisions, performance will decrease.
local function new(self, loop, func, delay, ...)
Major assumptions upheld: if delay < 0.01 then
- ALLOWS scheduling multiple timers with the same funcref/method delay = 0.01 -- Restrict to the lowest time that the C_Timer API allows us
- ALLOWS scheduling more timers during OnUpdate processing end
- ALLOWS unscheduling ANY timer (including the current running one) at any time, including during OnUpdate processing
]] local timer = {
object = self,
local MAJOR, MINOR = "AceTimer-3.0", 5 func = func,
local AceTimer, oldminor = LibStub:NewLibrary(MAJOR, MINOR) looping = loop,
argsCount = select("#", ...),
if not AceTimer then return end -- No upgrade needed delay = delay,
ends = GetTime() + delay,
AceTimer.hash = AceTimer.hash or {} -- Array of [0..BUCKET-1] = linked list of timers (using .next member) ...
-- Linked list gets around ACE-88 and ACE-90. }
AceTimer.selfs = AceTimer.selfs or {} -- Array of [self]={[handle]=timerobj, [handle2]=timerobj2, ...}
AceTimer.frame = AceTimer.frame or CreateFrame("Frame", "AceTimer30Frame") activeTimers[timer] = timer
-- Lua APIs -- Create new timer closure to wrap the "timer" object
local assert, error, loadstring = assert, error, loadstring timer.callback = function()
local setmetatable, rawset, rawget = setmetatable, rawset, rawget if not timer.cancelled then
local select, pairs, type, next, tostring = select, pairs, type, next, tostring if type(timer.func) == "string" then
local floor, max, min = math.floor, math.max, math.min -- We manually set the unpack count to prevent issues with an arg set that contains nil and ends with nil
local tconcat = table.concat -- e.g. local t = {1, 2, nil, 3, nil} print(#t) will result in 2, instead of 5. This fixes said issue.
timer.object[timer.func](timer.object, unpack(timer, 1, timer.argsCount))
-- WoW APIs else
local GetTime = GetTime timer.func(unpack(timer, 1, timer.argsCount))
end
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script if timer.looping and not timer.cancelled then
-- GLOBALS: DEFAULT_CHAT_FRAME, geterrorhandler -- Compensate delay to get a perfect average delay, even if individual times don't match up perfectly
-- due to fps differences
-- Simple ONE-SHOT timer cache. Much more efficient than a full compost for our purposes. local time = GetTime()
local timerCache = nil local ndelay = timer.delay - (time - timer.ends)
-- Ensure the delay doesn't go below the threshold
--[[ if ndelay < 0.01 then ndelay = 0.01 end
Timers will not be fired more often than HZ-1 times per second. C_TimerAfter(ndelay, timer.callback)
Keep at intended speed PLUS ONE or we get bitten by floating point rounding errors (n.5 + 0.1 can be n.599999) timer.ends = time + ndelay
If this is ever LOWERED, all existing timers need to be enforced to have a delay >= 1/HZ on lib upgrade. else
If this number is ever changed, all entries need to be rehashed on lib upgrade. activeTimers[timer.handle or timer] = nil
]] end
local HZ = 11 end
end
--[[
Prime for good distribution C_TimerAfter(delay, timer.callback)
If this number is ever changed, all entries need to be rehashed on lib upgrade. return timer
]] end
local BUCKETS = 131
--- Schedule a new one-shot timer.
local hash = AceTimer.hash -- The timer will fire once in `delay` seconds, unless canceled before.
for i=1,BUCKETS do -- @param func Callback function for the timer pulse (funcref or method name).
hash[i] = hash[i] or false -- make it an integer-indexed array; it's faster than hashes -- @param delay Delay for the timer, in seconds.
end -- @param ... An optional, unlimited amount of arguments to pass to the callback function.
-- @usage
--[[ -- MyAddOn = LibStub("AceAddon-3.0"):NewAddon("MyAddOn", "AceTimer-3.0")
xpcall safecall implementation --
]] -- function MyAddOn:OnEnable()
local xpcall = xpcall -- self:ScheduleTimer("TimerFeedback", 5)
-- end
local function errorhandler(err) --
return geterrorhandler()(err) -- function MyAddOn:TimerFeedback()
end -- print("5 seconds passed")
-- end
local function CreateDispatcher(argCount) function AceTimer:ScheduleTimer(func, delay, ...)
local code = [[ if not func or not delay then
local xpcall, eh = ... -- our arguments are received as unnamed values in "..." since we don't have a proper function declaration error(MAJOR..": ScheduleTimer(callback, delay, args...): 'callback' and 'delay' must have set values.", 2)
local method, ARGS end
local function call() return method(ARGS) end if type(func) == "string" then
if type(self) ~= "table" then
local function dispatch(func, ...) error(MAJOR..": ScheduleTimer(callback, delay, args...): 'self' - must be a table.", 2)
method = func elseif not self[func] then
if not method then return end error(MAJOR..": ScheduleTimer(callback, delay, args...): Tried to register '"..func.."' as the callback, but it doesn't exist in the module.", 2)
ARGS = ... end
return xpcall(call, eh) end
end return new(self, nil, func, delay, ...)
end
return dispatch
]] --- Schedule a repeating timer.
-- The timer will fire every `delay` seconds, until canceled.
local ARGS = {} -- @param func Callback function for the timer pulse (funcref or method name).
for i = 1, argCount do ARGS[i] = "arg"..i end -- @param delay Delay for the timer, in seconds.
code = code:gsub("ARGS", tconcat(ARGS, ", ")) -- @param ... An optional, unlimited amount of arguments to pass to the callback function.
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler) -- @usage
end -- MyAddOn = LibStub("AceAddon-3.0"):NewAddon("MyAddOn", "AceTimer-3.0")
--
local Dispatchers = setmetatable({}, { -- function MyAddOn:OnEnable()
__index=function(self, argCount) -- self.timerCount = 0
local dispatcher = CreateDispatcher(argCount) -- self.testTimer = self:ScheduleRepeatingTimer("TimerFeedback", 5)
rawset(self, argCount, dispatcher) -- end
return dispatcher --
end -- function MyAddOn:TimerFeedback()
}) -- self.timerCount = self.timerCount + 1
Dispatchers[0] = function(func) -- print(("%d seconds passed"):format(5 * self.timerCount))
return xpcall(func, errorhandler) -- -- run 30 seconds in total
end -- if self.timerCount == 6 then
-- self:CancelTimer(self.testTimer)
local function safecall(func, ...) -- end
return Dispatchers[select('#', ...)](func, ...) -- end
end function AceTimer:ScheduleRepeatingTimer(func, delay, ...)
if not func or not delay then
local lastint = floor(GetTime() * HZ) error(MAJOR..": ScheduleRepeatingTimer(callback, delay, args...): 'callback' and 'delay' must have set values.", 2)
end
-- -------------------------------------------------------------------- if type(func) == "string" then
-- OnUpdate handler if type(self) ~= "table" then
-- error(MAJOR..": ScheduleRepeatingTimer(callback, delay, args...): 'self' - must be a table.", 2)
-- traverse buckets, always chasing "now", and fire timers that have expired elseif not self[func] then
error(MAJOR..": ScheduleRepeatingTimer(callback, delay, args...): Tried to register '"..func.."' as the callback, but it doesn't exist in the module.", 2)
local function OnUpdate() end
local now = GetTime() end
local nowint = floor(now * HZ) return new(self, true, func, delay, ...)
end
-- Have we passed into a new hash bucket?
if nowint == lastint then return end --- Cancels a timer with the given id, registered by the same addon object as used for `:ScheduleTimer`
-- Both one-shot and repeating timers can be canceled with this function, as long as the `id` is valid
local soon = now + 1 -- +1 is safe as long as 1 < HZ < BUCKETS/2 -- and the timer has not fired yet or was canceled before.
-- @param id The id of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
-- Pass through each bucket at most once function AceTimer:CancelTimer(id)
-- Happens on e.g. instance loads, but COULD happen on high local load situations also local timer = activeTimers[id]
for curint = (max(lastint, nowint - BUCKETS) + 1), nowint do -- loop until we catch up with "now", usually only 1 iteration
local curbucket = (curint % BUCKETS)+1 if not timer then
-- Yank the list of timers out of the bucket and empty it. This allows reinsertion in the currently-processed bucket from callbacks. return false
local nexttimer = hash[curbucket] else
hash[curbucket] = false -- false rather than nil to prevent the array from becoming a hash timer.cancelled = true
activeTimers[id] = nil
while nexttimer do return true
local timer = nexttimer end
nexttimer = timer.next end
local when = timer.when
--- Cancels all timers registered to the current addon object ('self')
if when < soon then function AceTimer:CancelAllTimers()
-- Call the timer func, either as a method on given object, or a straight function ref for k,v in next, activeTimers do
local callback = timer.callback if v.object == self then
if type(callback) == "string" then AceTimer.CancelTimer(self, k)
safecall(timer.object[callback], timer.object, timer.arg) end
elseif callback then end
safecall(callback, timer.arg) end
else
-- probably nilled out by CancelTimer --- Returns the time left for a timer with the given id, registered by the current addon object ('self').
timer.delay = nil -- don't reschedule it -- This function will return 0 when the id is invalid.
end -- @param id The id of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
-- @return The time left on the timer.
local delay = timer.delay -- NOW make a local copy, can't do it earlier in case the timer cancelled itself in the callback function AceTimer:TimeLeft(id)
local timer = activeTimers[id]
if not delay then if not timer then
-- single-shot timer (or cancelled) return 0
AceTimer.selfs[timer.object][tostring(timer)] = nil else
timerCache = timer return timer.ends - GetTime()
else end
-- repeating timer end
local newtime = when + delay
if newtime < now then -- Keep lag from making us firing a timer unnecessarily. (Note that this still won't catch too-short-delay timers though.)
newtime = now + delay -- ---------------------------------------------------------------------
end -- Upgrading
timer.when = newtime
-- Upgrade from old hash-bucket based timers to C_Timer.After timers.
-- add next timer execution to the correct bucket if oldminor and oldminor < 10 then
local bucket = (floor(newtime * HZ) % BUCKETS) + 1 -- disable old timer logic
timer.next = hash[bucket] AceTimer.frame:SetScript("OnUpdate", nil)
hash[bucket] = timer AceTimer.frame:SetScript("OnEvent", nil)
end AceTimer.frame:UnregisterAllEvents()
else -- if when>=soon -- convert timers
-- reinsert (yeah, somewhat expensive, but shouldn't be happening too often either due to hash distribution) for object,timers in next, AceTimer.selfs do
timer.next = hash[curbucket] for handle,timer in next, timers do
hash[curbucket] = timer if type(timer) == "table" and timer.callback then
end -- if when<soon ... else local newTimer
end -- while nexttimer do if timer.delay then
end -- for curint=lastint,nowint newTimer = AceTimer.ScheduleRepeatingTimer(timer.object, timer.callback, timer.delay, timer.arg)
else
lastint = nowint newTimer = AceTimer.ScheduleTimer(timer.object, timer.callback, timer.when - GetTime(), timer.arg)
end end
-- Use the old handle for old timers
-- --------------------------------------------------------------------- activeTimers[newTimer] = nil
-- Reg( callback, delay, arg, repeating ) activeTimers[handle] = newTimer
-- newTimer.handle = handle
-- callback( function or string ) - direct function ref or method name in our object for the callback end
-- delay(int) - delay for the timer end
-- arg(variant) - any argument to be passed to the callback function end
-- repeating(boolean) - repeating timer, or oneshot AceTimer.selfs = nil
-- AceTimer.hash = nil
-- returns the handle of the timer for later processing (canceling etc) AceTimer.debug = nil
local function Reg(self, callback, delay, arg, repeating) elseif oldminor and oldminor < 17 then
if type(callback) ~= "string" and type(callback) ~= "function" then -- Upgrade from old animation based timers to C_Timer.After timers.
local error_origin = repeating and "ScheduleRepeatingTimer" or "ScheduleTimer" AceTimer.inactiveTimers = nil
error(MAJOR..": " .. error_origin .. "(callback, delay, arg): 'callback' - function or method name expected.", 3) AceTimer.frame = nil
end local oldTimers = AceTimer.activeTimers
if type(callback) == "string" then -- Clear old timer table and update upvalue
if type(self)~="table" then AceTimer.activeTimers = {}
local error_origin = repeating and "ScheduleRepeatingTimer" or "ScheduleTimer" activeTimers = AceTimer.activeTimers
error(MAJOR..": " .. error_origin .. "(\"methodName\", delay, arg): 'self' - must be a table.", 3) for handle, timer in next, oldTimers do
end local newTimer
if type(self[callback]) ~= "function" then -- Stop the old timer animation
local error_origin = repeating and "ScheduleRepeatingTimer" or "ScheduleTimer" local duration, elapsed = timer:GetDuration(), timer:GetElapsed()
error(MAJOR..": " .. error_origin .. "(\"methodName\", delay, arg): 'methodName' - method not found on target object.", 3) timer:GetParent():Stop()
end if timer.looping then
end newTimer = AceTimer.ScheduleRepeatingTimer(timer.object, timer.func, duration, unpack(timer.args, 1, timer.argsCount))
else
if delay < (1 / (HZ - 1)) then newTimer = AceTimer.ScheduleTimer(timer.object, timer.func, duration - elapsed, unpack(timer.args, 1, timer.argsCount))
delay = 1 / (HZ - 1) end
end -- Use the old handle for old timers
activeTimers[newTimer] = nil
-- Create and stuff timer in the correct hash bucket activeTimers[handle] = newTimer
local now = GetTime() newTimer.handle = handle
end
local timer = timerCache or {} -- Get new timer object (from cache if available)
timerCache = nil -- Migrate transitional handles
if oldminor < 13 and AceTimer.hashCompatTable then
timer.object = self for handle, id in next, AceTimer.hashCompatTable do
timer.callback = callback local t = activeTimers[id]
timer.delay = (repeating and delay) if t then
timer.arg = arg activeTimers[id] = nil
timer.when = now + delay activeTimers[handle] = t
t.handle = handle
local bucket = (floor((now+delay)*HZ) % BUCKETS) + 1 end
timer.next = hash[bucket] end
hash[bucket] = timer AceTimer.hashCompatTable = nil
end
-- Insert timer in our self->handle->timer registry end
local handle = tostring(timer)
-- ---------------------------------------------------------------------
local selftimers = AceTimer.selfs[self] -- Embed handling
if not selftimers then
selftimers = {} AceTimer.embeds = AceTimer.embeds or {}
AceTimer.selfs[self] = selftimers
end local mixins = {
selftimers[handle] = timer "ScheduleTimer", "ScheduleRepeatingTimer",
selftimers.__ops = (selftimers.__ops or 0) + 1 "CancelTimer", "CancelAllTimers",
"TimeLeft"
return handle }
end
function AceTimer:Embed(target)
--- Schedule a new one-shot timer. AceTimer.embeds[target] = true
-- The timer will fire once in `delay` seconds, unless canceled before. for _,v in next, mixins do
-- @param callback Callback function for the timer pulse (funcref or method name). target[v] = AceTimer[v]
-- @param delay Delay for the timer, in seconds. end
-- @param arg An optional argument to be passed to the callback function. return target
-- @usage end
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("TimerTest", "AceTimer-3.0")
-- -- AceTimer:OnEmbedDisable(target)
-- function MyAddon:OnEnable() -- target (object) - target object that AceTimer is embedded in.
-- self:ScheduleTimer("TimerFeedback", 5) --
-- end -- cancel all timers registered for the object
-- function AceTimer:OnEmbedDisable(target)
-- function MyAddon:TimerFeedback() target:CancelAllTimers()
-- print("5 seconds passed") end
-- end
function AceTimer:ScheduleTimer(callback, delay, arg) for addon in next, AceTimer.embeds do
return Reg(self, callback, delay, arg) AceTimer:Embed(addon)
end end
--- Schedule a repeating timer.
-- The timer will fire every `delay` seconds, until canceled.
-- @param callback Callback function for the timer pulse (funcref or method name).
-- @param delay Delay for the timer, in seconds.
-- @param arg An optional argument to be passed to the callback function.
-- @usage
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("TimerTest", "AceTimer-3.0")
--
-- function MyAddon:OnEnable()
-- self.timerCount = 0
-- self.testTimer = self:ScheduleRepeatingTimer("TimerFeedback", 5)
-- end
--
-- function MyAddon:TimerFeedback()
-- self.timerCount = self.timerCount + 1
-- print(("%d seconds passed"):format(5 * self.timerCount))
-- -- run 30 seconds in total
-- if self.timerCount == 6 then
-- self:CancelTimer(self.testTimer)
-- end
-- end
function AceTimer:ScheduleRepeatingTimer(callback, delay, arg)
return Reg(self, callback, delay, arg, true)
end
--- Cancels a timer with the given handle, registered by the same addon object as used for `:ScheduleTimer`
-- Both one-shot and repeating timers can be canceled with this function, as long as the `handle` is valid
-- and the timer has not fired yet or was canceled before.
-- @param handle The handle of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
-- @param silent If true, no error is raised if the timer handle is invalid (expired or already canceled)
-- @return True if the timer was successfully cancelled.
function AceTimer:CancelTimer(handle, silent)
if not handle then return end -- nil handle -> bail out without erroring
if type(handle) ~= "string" then
error(MAJOR..": CancelTimer(handle): 'handle' - expected a string", 2) -- for now, anyway
end
local selftimers = AceTimer.selfs[self]
local timer = selftimers and selftimers[handle]
if silent then
if timer then
timer.callback = nil -- don't run it again
timer.delay = nil -- if this is the currently-executing one: don't even reschedule
-- The timer object is removed in the OnUpdate loop
end
return not not timer -- might return "true" even if we double-cancel. we'll live.
else
if not timer then
geterrorhandler()(MAJOR..": CancelTimer(handle[, silent]): '"..tostring(handle).."' - no such timer registered")
return false
end
if not timer.callback then
geterrorhandler()(MAJOR..": CancelTimer(handle[, silent]): '"..tostring(handle).."' - timer already cancelled or expired")
return false
end
timer.callback = nil -- don't run it again
timer.delay = nil -- if this is the currently-executing one: don't even reschedule
return true
end
end
--- Cancels all timers registered to the current addon object ('self')
function AceTimer:CancelAllTimers()
if not(type(self) == "string" or type(self) == "table") then
error(MAJOR..": CancelAllTimers(): 'self' - must be a string or a table",2)
end
if self == AceTimer then
error(MAJOR..": CancelAllTimers(): supply a meaningful 'self'", 2)
end
local selftimers = AceTimer.selfs[self]
if selftimers then
for handle,v in pairs(selftimers) do
if type(v) == "table" then -- avoid __ops, etc
AceTimer.CancelTimer(self, handle, true)
end
end
end
end
--- Returns the time left for a timer with the given handle, registered by the current addon object ('self').
-- This function will raise a warning when the handle is invalid, but not stop execution.
-- @param handle The handle of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
-- @return The time left on the timer, or false if the handle is invalid.
function AceTimer:TimeLeft(handle)
if not handle then return end
if type(handle) ~= "string" then
error(MAJOR..": TimeLeft(handle): 'handle' - expected a string", 2) -- for now, anyway
end
local selftimers = AceTimer.selfs[self]
local timer = selftimers and selftimers[handle]
if not timer then
geterrorhandler()(MAJOR..": TimeLeft(handle): '"..tostring(handle).."' - no such timer registered")
return false
end
return timer.when - GetTime()
end
-- ---------------------------------------------------------------------
-- PLAYER_REGEN_ENABLED: Run through our .selfs[] array step by step
-- and clean it out - otherwise the table indices can grow indefinitely
-- if an addon starts and stops a lot of timers. AceBucket does this!
--
-- See ACE-94 and tests/AceTimer-3.0-ACE-94.lua
local lastCleaned = nil
local function OnEvent(this, event)
if event~="PLAYER_REGEN_ENABLED" then
return
end
-- Get the next 'self' to process
local selfs = AceTimer.selfs
local self = next(selfs, lastCleaned)
if not self then
self = next(selfs)
end
lastCleaned = self
if not self then -- should only happen if .selfs[] is empty
return
end
-- Time to clean it out?
local list = selfs[self]
if (list.__ops or 0) < 250 then -- 250 slosh indices = ~10KB wasted (max!). For one 'self'.
return
end
-- Create a new table and copy all members over
local newlist = {}
local n=0
for k,v in pairs(list) do
newlist[k] = v
n=n+1
end
newlist.__ops = 0 -- Reset operation count
-- And since we now have a count of the number of live timers, check that it's reasonable. Emit a warning if not.
if n>BUCKETS then
DEFAULT_CHAT_FRAME:AddMessage(MAJOR..": Warning: The addon/module '"..tostring(self).."' has "..n.." live timers. Surely that's not intended?")
end
selfs[self] = newlist
end
-- ---------------------------------------------------------------------
-- Embed handling
AceTimer.embeds = AceTimer.embeds or {}
local mixins = {
"ScheduleTimer", "ScheduleRepeatingTimer",
"CancelTimer", "CancelAllTimers",
"TimeLeft"
}
function AceTimer:Embed(target)
AceTimer.embeds[target] = true
for _,v in pairs(mixins) do
target[v] = AceTimer[v]
end
return target
end
-- AceTimer:OnEmbedDisable( target )
-- target (object) - target object that AceTimer is embedded in.
--
-- cancel all timers registered for the object
function AceTimer:OnEmbedDisable( target )
target:CancelAllTimers()
end
for addon in pairs(AceTimer.embeds) do
AceTimer:Embed(addon)
end
-- ---------------------------------------------------------------------
-- Debug tools (expose copies of internals to test suites)
AceTimer.debug = AceTimer.debug or {}
AceTimer.debug.HZ = HZ
AceTimer.debug.BUCKETS = BUCKETS
-- ---------------------------------------------------------------------
-- Finishing touchups
AceTimer.frame:SetScript("OnUpdate", OnUpdate)
AceTimer.frame:SetScript("OnEvent", OnEvent)
AceTimer.frame:RegisterEvent("PLAYER_REGEN_ENABLED")
-- In theory, we should hide&show the frame based on there being timers or not.
-- However, this job is fairly expensive, and the chance that there will
-- actually be zero timers running is diminuitive to say the lest.
+3 -3
View File
@@ -1,4 +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/ <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"> ..\FrameXML\UI.xsd">
<Script file="AceTimer-3.0.lua"/> <Script file="AceTimer-3.0.lua"/>
</Ui> </Ui>
+202 -239
View File
@@ -1,239 +1,202 @@
--[[ $Id: CallbackHandler-1.0.lua 3 2008-09-29 16:54:20Z nevcairiel $ ]] --[[ $Id: CallbackHandler-1.0.lua 25 2022-12-12 15:02:36Z nevcairiel $ ]]
local MAJOR, MINOR = "CallbackHandler-1.0", 3 local MAJOR, MINOR = "CallbackHandler-1.0", 8
local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR) local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR)
if not CallbackHandler then return end -- No upgrade needed if not CallbackHandler then return end -- No upgrade needed
local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end} local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end}
local type = type -- Lua APIs
local pcall = pcall local securecallfunction, error = securecallfunction, error
local pairs = pairs local setmetatable, rawget = setmetatable, rawget
local assert = assert local next, select, pairs, type, tostring = next, select, pairs, type, tostring
local concat = table.concat
local loadstring = loadstring
local next = next local function Dispatch(handlers, ...)
local select = select local index, method = next(handlers)
local type = type if not method then return end
local xpcall = xpcall repeat
securecallfunction(method, ...)
local function errorhandler(err) index, method = next(handlers, index)
return geterrorhandler()(err) until not method
end end
local function CreateDispatcher(argCount) --------------------------------------------------------------------------
local code = [[ -- CallbackHandler:New
local next, xpcall, eh = ... --
-- target - target object to embed public APIs in
local method, ARGS -- RegisterName - name of the callback registration API, default "RegisterCallback"
local function call() method(ARGS) end -- UnregisterName - name of the callback unregistration API, default "UnregisterCallback"
-- UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API.
local function dispatch(handlers, ...)
local index function CallbackHandler.New(_self, target, RegisterName, UnregisterName, UnregisterAllName)
index, method = next(handlers)
if not method then return end RegisterName = RegisterName or "RegisterCallback"
local OLD_ARGS = ARGS UnregisterName = UnregisterName or "UnregisterCallback"
ARGS = ... if UnregisterAllName==nil then -- false is used to indicate "don't want this method"
repeat UnregisterAllName = "UnregisterAllCallbacks"
xpcall(call, eh) end
index, method = next(handlers, index)
until not method -- we declare all objects and exported APIs inside this closure to quickly gain access
ARGS = OLD_ARGS -- to e.g. function names, the "target" parameter, etc
end
return dispatch -- Create the registry object
]] local events = setmetatable({}, meta)
local registry = { recurse=0, events=events }
local ARGS, OLD_ARGS = {}, {}
for i = 1, argCount do ARGS[i], OLD_ARGS[i] = "arg"..i, "old_arg"..i end -- registry:Fire() - fires the given event/message into the registry
code = code:gsub("OLD_ARGS", concat(OLD_ARGS, ", ")):gsub("ARGS", concat(ARGS, ", ")) function registry:Fire(eventname, ...)
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(next, xpcall, errorhandler) if not rawget(events, eventname) or not next(events[eventname]) then return end
end local oldrecurse = registry.recurse
registry.recurse = oldrecurse + 1
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount) Dispatch(events[eventname], eventname, ...)
rawset(self, argCount, dispatcher)
return dispatcher registry.recurse = oldrecurse
end})
if registry.insertQueue and oldrecurse==0 then
-------------------------------------------------------------------------- -- Something in one of our callbacks wanted to register more callbacks; they got queued
-- CallbackHandler:New for event,callbacks in pairs(registry.insertQueue) do
-- local first = not rawget(events, event) or not next(events[event]) -- test for empty before. not test for one member after. that one member may have been overwritten.
-- target - target object to embed public APIs in for object,func in pairs(callbacks) do
-- RegisterName - name of the callback registration API, default "RegisterCallback" events[event][object] = func
-- UnregisterName - name of the callback unregistration API, default "UnregisterCallback" -- fire OnUsed callback?
-- UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API. if first and registry.OnUsed then
registry.OnUsed(registry, target, event)
function CallbackHandler:New(target, RegisterName, UnregisterName, UnregisterAllName, OnUsed, OnUnused) first = nil
-- TODO: Remove this after beta has gone out end
assert(not OnUsed and not OnUnused, "ACE-80: OnUsed/OnUnused are deprecated. Callbacks are now done to registry.OnUsed and registry.OnUnused") end
end
RegisterName = RegisterName or "RegisterCallback" registry.insertQueue = nil
UnregisterName = UnregisterName or "UnregisterCallback" end
if UnregisterAllName==nil then -- false is used to indicate "don't want this method" end
UnregisterAllName = "UnregisterAllCallbacks"
end -- Registration of a callback, handles:
-- self["method"], leads to self["method"](self, ...)
-- we declare all objects and exported APIs inside this closure to quickly gain access -- self with function ref, leads to functionref(...)
-- to e.g. function names, the "target" parameter, etc -- "addonId" (instead of self) with function ref, leads to functionref(...)
-- all with an optional arg, which, if present, gets passed as first argument (after self if present)
target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]])
-- Create the registry object if type(eventname) ~= "string" then
local events = setmetatable({}, meta) error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2)
local registry = { recurse=0, events=events } end
-- registry:Fire() - fires the given event/message into the registry method = method or eventname
function registry:Fire(eventname, ...)
if not rawget(events, eventname) or not next(events[eventname]) then return end local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
local oldrecurse = registry.recurse
registry.recurse = oldrecurse + 1 if type(method) ~= "string" and type(method) ~= "function" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2)
Dispatchers[select('#', ...) + 1](events[eventname], eventname, ...) end
registry.recurse = oldrecurse local regfunc
if registry.insertQueue and oldrecurse==0 then if type(method) == "string" then
-- Something in one of our callbacks wanted to register more callbacks; they got queued -- self["method"] calling style
for eventname,callbacks in pairs(registry.insertQueue) do if type(self) ~= "table" then
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten. error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2)
for self,func in pairs(callbacks) do elseif self==target then
events[eventname][self] = func error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2)
-- fire OnUsed callback? elseif type(self[method]) ~= "function" then
if first and registry.OnUsed then error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2)
registry.OnUsed(registry, target, eventname) end
first = nil
end if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
end local arg=select(1,...)
end regfunc = function(...) self[method](self,arg,...) end
registry.insertQueue = nil else
end regfunc = function(...) self[method](self,...) end
end end
else
-- Registration of a callback, handles: -- function ref with self=object or self="addonId" or self=thread
-- self["method"], leads to self["method"](self, ...) if type(self)~="table" and type(self)~="string" and type(self)~="thread" then
-- self with function ref, leads to functionref(...) error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string or thread expected.", 2)
-- "addonId" (instead of self) with function ref, leads to functionref(...) end
-- all with an optional arg, which, if present, gets passed as first argument (after self if present)
target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]]) if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
if type(eventname) ~= "string" then local arg=select(1,...)
error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2) regfunc = function(...) method(arg,...) end
end else
regfunc = method
method = method or eventname end
end
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
if type(method) ~= "string" and type(method) ~= "function" then if events[eventname][self] or registry.recurse<1 then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2) -- if registry.recurse<1 then
end -- we're overwriting an existing entry, or not currently recursing. just set it.
events[eventname][self] = regfunc
local regfunc -- fire OnUsed callback?
if registry.OnUsed and first then
if type(method) == "string" then registry.OnUsed(registry, target, eventname)
-- self["method"] calling style end
if type(self) ~= "table" then else
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2) -- we're currently processing a callback in this registry, so delay the registration of this new entry!
elseif self==target then -- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2) registry.insertQueue = registry.insertQueue or setmetatable({},meta)
elseif type(self[method]) ~= "function" then registry.insertQueue[eventname][self] = regfunc
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2) end
end end
if select("#",...)>=1 then -- this is not the same as testing for arg==nil! -- Unregister a callback
local arg=select(1,...) target[UnregisterName] = function(self, eventname)
regfunc = function(...) self[method](self,arg,...) end if not self or self==target then
else error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2)
regfunc = function(...) self[method](self,...) end end
end if type(eventname) ~= "string" then
else error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2)
-- function ref with self=object or self="addonId" end
if type(self)~="table" and type(self)~="string" then if rawget(events, eventname) and events[eventname][self] then
error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string expected.", 2) events[eventname][self] = nil
end -- Fire OnUnused callback?
if registry.OnUnused and not next(events[eventname]) then
if select("#",...)>=1 then -- this is not the same as testing for arg==nil! registry.OnUnused(registry, target, eventname)
local arg=select(1,...) end
regfunc = function(...) method(arg,...) end end
else if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then
regfunc = method registry.insertQueue[eventname][self] = nil
end end
end end
-- OPTIONAL: Unregister all callbacks for given selfs/addonIds
if events[eventname][self] or registry.recurse<1 then if UnregisterAllName then
-- if registry.recurse<1 then target[UnregisterAllName] = function(...)
-- we're overwriting an existing entry, or not currently recursing. just set it. if select("#",...)<1 then
events[eventname][self] = regfunc error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2)
-- fire OnUsed callback? end
if registry.OnUsed and first then if select("#",...)==1 and ...==target then
registry.OnUsed(registry, target, eventname) error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2)
end end
else
-- we're currently processing a callback in this registry, so delay the registration of this new entry!
-- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency for i=1,select("#",...) do
registry.insertQueue = registry.insertQueue or setmetatable({},meta) local self = select(i,...)
registry.insertQueue[eventname][self] = regfunc if registry.insertQueue then
end for eventname, callbacks in pairs(registry.insertQueue) do
end if callbacks[self] then
callbacks[self] = nil
-- Unregister a callback end
target[UnregisterName] = function(self, eventname) end
if not self or self==target then end
error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2) for eventname, callbacks in pairs(events) do
end if callbacks[self] then
if type(eventname) ~= "string" then callbacks[self] = nil
error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2) -- Fire OnUnused callback?
end if registry.OnUnused and not next(callbacks) then
if rawget(events, eventname) and events[eventname][self] then registry.OnUnused(registry, target, eventname)
events[eventname][self] = nil end
-- Fire OnUnused callback? end
if registry.OnUnused and not next(events[eventname]) then end
registry.OnUnused(registry, target, eventname) end
end end
end end
if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then
registry.insertQueue[eventname][self] = nil return registry
end end
end
-- OPTIONAL: Unregister all callbacks for given selfs/addonIds -- CallbackHandler purposefully does NOT do explicit embedding. Nor does it
if UnregisterAllName then -- try to upgrade old implicit embeds since the system is selfcontained and
target[UnregisterAllName] = function(...) -- relies on closures to work.
if select("#",...)<1 then
error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2)
end
if select("#",...)==1 and ...==target then
error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2)
end
for i=1,select("#",...) do
local self = select(i,...)
if registry.insertQueue then
for eventname, callbacks in pairs(registry.insertQueue) do
if callbacks[self] then
callbacks[self] = nil
end
end
end
for eventname, callbacks in pairs(events) do
if callbacks[self] then
callbacks[self] = nil
-- Fire OnUnused callback?
if registry.OnUnused and not next(callbacks) then
registry.OnUnused(registry, target, eventname)
end
end
end
end
end
end
return registry
end
-- CallbackHandler purposefully does NOT do explicit embedding. Nor does it
-- try to upgrade old implicit embeds since the system is selfcontained and
-- relies on closures to work.
@@ -1,4 +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/ <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"> ..\FrameXML\UI.xsd">
<Script file="CallbackHandler-1.0.lua"/> <Script file="CallbackHandler-1.0.lua"/>
</Ui> </Ui>
+30 -30
View File
@@ -1,30 +1,30 @@
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info -- 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 -- 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_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
local LibStub = _G[LIBSTUB_MAJOR] local LibStub = _G[LIBSTUB_MAJOR]
if not LibStub or LibStub.minor < LIBSTUB_MINOR then if not LibStub or LibStub.minor < LIBSTUB_MINOR then
LibStub = LibStub or {libs = {}, minors = {} } LibStub = LibStub or {libs = {}, minors = {} }
_G[LIBSTUB_MAJOR] = LibStub _G[LIBSTUB_MAJOR] = LibStub
LibStub.minor = LIBSTUB_MINOR LibStub.minor = LIBSTUB_MINOR
function LibStub:NewLibrary(major, minor) function LibStub:NewLibrary(major, minor)
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)") 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.") minor = assert(tonumber(string.match(minor, "%d+")), "Minor version must either be a number or contain a number.")
local oldminor = self.minors[major] local oldminor = self.minors[major]
if oldminor and oldminor >= minor then return nil end if oldminor and oldminor >= minor then return nil end
self.minors[major], self.libs[major] = minor, self.libs[major] or {} self.minors[major], self.libs[major] = minor, self.libs[major] or {}
return self.libs[major], oldminor return self.libs[major], oldminor
end end
function LibStub:GetLibrary(major, silent) function LibStub:GetLibrary(major, silent)
if not self.libs[major] and not silent then if not self.libs[major] and not silent then
error(("Cannot find a library instance of %q."):format(tostring(major)), 2) error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
end end
return self.libs[major], self.minors[major] return self.libs[major], self.minors[major]
end end
function LibStub:IterateLibraries() return pairs(self.libs) end function LibStub:IterateLibraries() return pairs(self.libs) end
setmetatable(LibStub, { __call = LibStub.GetLibrary }) setmetatable(LibStub, { __call = LibStub.GetLibrary })
end end
-13
View File
@@ -1,13 +0,0 @@
## Interface: 20400
## Title: Lib: LibStub
## Notes: Universal Library Stub
## Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel
## X-Website: http://jira.wowace.com/browse/LS
## X-Category: Library
## X-License: Public Domain
## X-Curse-Packaged-Version: 1.0
## X-Curse-Project-Name: LibStub
## X-Curse-Project-ID: libstub
## X-Curse-Repository-ID: wow/libstub/mainline
LibStub.lua