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:
+649
-642
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="AceAddon-3.0.lua"/>
|
<Script file="AceAddon-3.0.lua"/>
|
||||||
</Ui>
|
</Ui>
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -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
|
|
||||||
|
|||||||
@@ -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>
|
||||||
+797
-712
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="AceDB-3.0.lua"/>
|
<Script file="AceDB-3.0.lua"/>
|
||||||
</Ui>
|
</Ui>
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
+1020
-863
File diff suppressed because it is too large
Load Diff
@@ -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)
|
||||||
+336
-328
@@ -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
|
|
||||||
@@ -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
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
|
|||||||
@@ -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
@@ -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.
|
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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
|
|
||||||
Reference in New Issue
Block a user