WoWInterface SVN PocketPlot

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /trunk/PocketPlot/libs/AceConfig-3.0
    from Rev 88 to Rev 89
    Reverse comparison

Rev 88 → Rev 89

AceConfigRegistry-3.0/AceConfigRegistry-3.0.lua
4,14 → 4,14
-- * 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 **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".
-- @class file
-- @name AceConfigRegistry-3.0
-- @release $Id: AceConfigRegistry-3.0.lua 1169 2018-02-27 16:18:28Z nevcairiel $
-- @release $Id: AceConfigRegistry-3.0.lua 1207 2019-06-23 12:08:33Z nevcairiel $
local CallbackHandler = LibStub("CallbackHandler-1.0")
 
local MAJOR, MINOR = "AceConfigRegistry-3.0", 18
local MAJOR, MINOR = "AceConfigRegistry-3.0", 20
local AceConfigRegistry = LibStub:NewLibrary(MAJOR, MINOR)
 
if not AceConfigRegistry then return end
33,7 → 33,7
 
 
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
cmd = {},
dropdown = {},
59,7 → 59,6
local optstringfunc={["nil"]=true,["string"]=true,["function"]=true, _="string or funcref"}
local optstringnumberfunc={["nil"]=true,["string"]=true,["number"]=true,["function"]=true, _="string, number or funcref"}
local optnumber={["nil"]=true,["number"]=true, _="number"}
local optmethod={["nil"]=true,["string"]=true,["function"]=true, _="methodname or funcref"}
local optmethodfalse={["nil"]=true,["string"]=true,["function"]=true,["boolean"]={[false]=true}, _="methodname, funcref or false"}
local optmethodnumber={["nil"]=true,["string"]=true,["function"]=true,["number"]=true, _="methodname, funcref or number"}
local optmethodtable={["nil"]=true,["string"]=true,["function"]=true,["table"]=true, _="methodname, funcref or table"}
95,13 → 94,20
}
 
local typedkeys={
header={},
header={
control=optstring,
dialogControl=optstring,
dropdownControl=optstring,
},
description={
image=optstringnumberfunc,
imageCoords=optmethodtable,
imageHeight=optnumber,
imageWidth=optnumber,
fontSize=optstringfunc,
control=optstring,
dialogControl=optstring,
dropdownControl=optstring,
},
group={
args=istable,
118,6 → 124,9
imageCoords=optmethodtable,
imageHeight=optnumber,
imageWidth=optnumber,
control=optstring,
dialogControl=optstring,
dropdownControl=optstring,
},
input={
pattern=optstring,
131,6 → 140,9
tristate=optbool,
image=optstringnumberfunc,
imageCoords=optmethodtable,
control=optstring,
dialogControl=optstring,
dropdownControl=optstring,
},
tristate={
},
142,12 → 154,16
step=optnumber,
bigStep=optnumber,
isPercent=optbool,
control=optstring,
dialogControl=optstring,
dropdownControl=optstring,
},
select={
values=ismethodtable,
sorting=optmethodtable,
style={
["nil"]=true,
["string"]={dropdown=true,radio=true},
["nil"]=true,
["string"]={dropdown=true,radio=true},
_="string: 'dropdown' or 'radio'"
},
control=optstring,
165,9 → 181,14
},
color={
hasAlpha=optmethodbool,
control=optstring,
dialogControl=optstring,
dropdownControl=optstring,
},
keybinding={
-- TODO
control=optstring,
dialogControl=optstring,
dropdownControl=optstring,
},
}
 
204,13 → 225,13
if type(options.type)~="string" then
err(".type: expected a string, got a "..type(options.type), errlvl,...)
end
 
 
-- get type and 'typedkeys' member
local tk = typedkeys[options.type]
if not tk then
err(".type: unknown type '"..options.type.."'", errlvl,...)
end
 
 
-- make sure that all options[] are known parameters
for k,v in pairs(options) do
if not (tk[k] or basekeys[k]) then
303,7 → 324,7
AceConfigRegistry:ValidateOptionsTable(options, appName, errlvl) -- upgradable
AceConfigRegistry.validated[uiType][appName] = true
end
return options
return options
end
elseif type(options)=="function" then
AceConfigRegistry.tables[appName] = function(uiType, uiName, errlvl)
341,7 → 362,7
if not f then
return nil
end
 
 
if uiType then
return f(uiType,uiName,1) -- get the table for us
else
AceConfig-3.0.lua
3,7 → 3,7
-- as well as associate it with a slash command.
-- @class file
-- @name AceConfig-3.0
-- @release $Id: AceConfig-3.0.lua 1161 2017-08-12 14:30:16Z funkydude $
-- @release $Id: AceConfig-3.0.lua 1202 2019-05-15 23:11:22Z nevcairiel $
 
--[[
AceConfig-3.0
45,7 → 45,7
function AceConfig:RegisterOptionsTable(appName, options, slashcmd)
local ok,msg = pcall(cfgreg.RegisterOptionsTable, self, appName, options)
if not ok then error(msg, 2) end
 
 
if slashcmd then
if type(slashcmd) == "table" then
for _,cmd in pairs(slashcmd) do
AceConfigDialog-3.0/AceConfigDialog-3.0.lua
1,13 → 1,13
--- AceConfigDialog-3.0 generates AceGUI-3.0 based windows based on option tables.
-- @class file
-- @name AceConfigDialog-3.0
-- @release $Id: AceConfigDialog-3.0.lua 1169 2018-02-27 16:18:28Z nevcairiel $
-- @release $Id: AceConfigDialog-3.0.lua 1232 2020-04-14 22:21:22Z nevcairiel $
 
local LibStub = LibStub
local gui = LibStub("AceGUI-3.0")
local reg = LibStub("AceConfigRegistry-3.0")
 
local MAJOR, MINOR = "AceConfigDialog-3.0", 66
local MAJOR, MINOR = "AceConfigDialog-3.0", 79
local AceConfigDialog, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
 
if not AceConfigDialog then return end
15,22 → 15,23
AceConfigDialog.OpenFrames = AceConfigDialog.OpenFrames or {}
AceConfigDialog.Status = AceConfigDialog.Status or {}
AceConfigDialog.frame = AceConfigDialog.frame or CreateFrame("Frame")
AceConfigDialog.tooltip = AceConfigDialog.tooltip or CreateFrame("GameTooltip", "AceConfigDialogTooltip", UIParent, "GameTooltipTemplate")
 
AceConfigDialog.frame.apps = AceConfigDialog.frame.apps or {}
AceConfigDialog.frame.closing = AceConfigDialog.frame.closing or {}
AceConfigDialog.frame.closeAllOverride = AceConfigDialog.frame.closeAllOverride or {}
 
-- Lua APIs
local tconcat, tinsert, tsort, tremove, tsort = table.concat, table.insert, table.sort, table.remove, table.sort
local tinsert, tsort, tremove = table.insert, table.sort, table.remove
local strmatch, format = string.match, string.format
local assert, loadstring, error = assert, loadstring, error
local error = error
local pairs, next, select, type, unpack, wipe, ipairs = pairs, next, select, type, unpack, wipe, ipairs
local rawset, tostring, tonumber = rawset, tostring, tonumber
local tostring, tonumber = tostring, tonumber
local math_min, math_max, math_floor = math.min, math.max, math.floor
 
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: NORMAL_FONT_COLOR, GameTooltip, StaticPopupDialogs, ACCEPT, CANCEL, StaticPopup_Show
-- GLOBALS: NORMAL_FONT_COLOR, ACCEPT, CANCEL
-- GLOBALS: PlaySound, GameFontHighlight, GameFontHighlightSmall, GameFontHighlightLarge
-- GLOBALS: CloseSpecialWindows, InterfaceOptions_AddCategory, geterrorhandler
 
45,39 → 46,10
return geterrorhandler()(err)
end
 
local function CreateDispatcher(argCount)
local code = [[
local xpcall, eh = ...
local method, ARGS
local function call() return method(ARGS) end
 
local function dispatch(func, ...)
method = func
if not method then return end
ARGS = ...
return xpcall(call, eh)
end
 
return dispatch
]]
 
local ARGS = {}
for i = 1, argCount do ARGS[i] = "arg"..i end
code = code:gsub("ARGS", tconcat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
end
 
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
end})
Dispatchers[0] = function(func)
return xpcall(func, errorhandler)
end
 
local function safecall(func, ...)
return Dispatchers[select("#", ...)](func, ...)
if func then
return xpcall(func, errorhandler, ...)
end
end
 
local width_multiplier = 170
85,18 → 57,18
--[[
Group Types
Tree - All Descendant Groups will all become nodes on the tree, direct child options will appear above the tree
- Descendant Groups with inline=true and thier children will not become nodes
- Descendant Groups with inline=true and thier children will not become nodes
 
Tab - Direct Child Groups will become tabs, direct child options will appear above the tab control
- Grandchild groups will default to inline unless specified otherwise
- Grandchild groups will default to inline unless specified otherwise
 
Select- Same as Tab but with entries in a dropdown rather than tabs
 
 
Inline Groups
- Will not become nodes of a select group, they will be effectivly part of thier parent group seperated by a border
- If declared on a direct child of a root node of a select group, they will appear above the group container control
- When a group is displayed inline, all descendants will also be inline members of the group
- Will not become nodes of a select group, they will be effectivly part of thier parent group seperated by a border
- If declared on a direct child of a root node of a select group, they will appear above the group container control
- When a group is displayed inline, all descendants will also be inline members of the group
 
]]
 
197,11 → 169,11
local function GetOptionsMemberValue(membername, option, options, path, appName, ...)
--get definition for the member
local inherits = isInherited[membername]
 
 
 
--get the member of the option, traversing the tree if it can be inherited
local member
 
 
if inherits then
local group = options
if group[membername] ~= nil then
216,7 → 188,7
else
member = option[membername]
end
 
 
--check if we need to call a functon, or if we have a literal value
if ( not allIsLiteral[membername] ) and ( type(member) == "function" or ((not stringIsLiteral[membername]) and type(member) == "string") ) then
--We have a function to call
225,13 → 197,13
local handler
local group = options
handler = group.handler or handler
 
 
for i = 1, #path do
group = GetSubOption(group, path[i])
info[i] = path[i]
handler = group.handler or handler
end
 
 
info.options = options
info.appName = appName
info[0] = appName
241,8 → 213,8
info.type = option.type
info.uiType = "dialog"
info.uiName = MAJOR
 
local a, b, c ,d
 
local a, b, c ,d
--using 4 returns for the get of a color type, increase if a type needs more
if type(member) == "function" then
--Call the function
259,8 → 231,8
return a,b,c,d
else
--The value isnt a function to call, return it
return member
end
return member
end
end
 
--[[calls an options function that could be inherited, method name or function ref
325,7 → 297,7
return NameA:upper() < NameB:upper()
end
if OrderA < 0 then
if OrderB > 0 then
if OrderB >= 0 then
return false
end
else
344,7 → 316,7
local function BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
tempOrders = new()
tempNames = new()
 
 
if group.plugins then
for plugin, t in pairs(group.plugins) do
for k, v in pairs(t) do
360,7 → 332,7
end
end
end
 
 
for k, v in pairs(group.args) do
if not opts[k] then
tinsert(keySort, k)
391,7 → 363,7
end
 
local function CleanUserData(widget, event)
 
 
local user = widget:GetUserDataTable()
 
if user.path then
431,7 → 403,7
-- - Gets a status table for the given appname and options path.
-- @param appName The application name as given to `:RegisterOptionsTable()`
-- @param path The path to the options (a table with all group keys)
-- @return
-- @return
function AceConfigDialog:GetStatusTable(appName, path)
local status = self.Status
 
465,7 → 437,7
function AceConfigDialog:SelectGroup(appName, ...)
local path = new()
 
 
 
local app = reg:GetOptionsTable(appName)
if not app then
error(("%s isn't registed with AceConfigRegistry, unable to open config"):format(appName), 2)
477,9 → 449,9
status.groups = {}
end
status = status.groups
local treevalue
local treestatus
 
local treevalue
local treestatus
 
for n = 1, select("#",...) do
local key = select(n, ...)
 
506,12 → 478,12
--the selected group will be overwritten if a child is the final target but still needs to be open
treestatus.selected = treevalue
treestatus.groups[treevalue] = true
 
 
end
 
 
--move to the next group in the path
group = GetSubOption(group, key)
if not group then
if not group then
break
end
tinsert(path, key)
521,10 → 493,10
end
status = status.groups
end
 
 
del(path)
reg:NotifyChange(appName)
end
end
 
local function OptionOnMouseOver(widget, event)
--show a tooltip/set the status bar to the desc text
533,32 → 505,33
local options = user.options
local path = user.path
local appName = user.appName
local tooltip = AceConfigDialog.tooltip
 
GameTooltip:SetOwner(widget.frame, "ANCHOR_TOPRIGHT")
tooltip:SetOwner(widget.frame, "ANCHOR_TOPRIGHT")
local name = GetOptionsMemberValue("name", opt, options, path, appName)
local desc = GetOptionsMemberValue("desc", opt, options, path, appName)
local usage = GetOptionsMemberValue("usage", opt, options, path, appName)
local descStyle = opt.descStyle
 
 
if descStyle and descStyle ~= "tooltip" then return end
 
GameTooltip:SetText(name, 1, .82, 0, true)
 
 
tooltip:SetText(name, 1, .82, 0, true)
 
if opt.type == "multiselect" then
GameTooltip:AddLine(user.text, 0.5, 0.5, 0.8, true)
end
tooltip:AddLine(user.text, 0.5, 0.5, 0.8, true)
end
if type(desc) == "string" then
GameTooltip:AddLine(desc, 1, 1, 1, true)
tooltip:AddLine(desc, 1, 1, 1, true)
end
if type(usage) == "string" then
GameTooltip:AddLine("Usage: "..usage, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, true)
tooltip:AddLine("Usage: "..usage, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, true)
end
 
GameTooltip:Show()
tooltip:Show()
end
 
local function OptionOnMouseLeave(widget, event)
GameTooltip:Hide()
AceConfigDialog.tooltip:Hide()
end
 
local function GetFuncName(option)
569,71 → 542,123
return "set"
end
end
do
local frame = AceConfigDialog.popup
if not frame then
frame = CreateFrame("Frame", nil, UIParent)
AceConfigDialog.popup = frame
frame:Hide()
frame:SetPoint("CENTER", UIParent, "CENTER")
frame:SetSize(320, 72)
frame:SetFrameStrata("TOOLTIP")
frame:SetScript("OnKeyDown", function(self, key)
if key == "ESCAPE" then
self:SetPropagateKeyboardInput(false)
if self.cancel:IsShown() then
self.cancel:Click()
else -- Showing a validation error
self:Hide()
end
else
self:SetPropagateKeyboardInput(true)
end
end)
 
if WOW_PROJECT_ID == WOW_PROJECT_CLASSIC then
frame:SetBackdrop({
bgFile = [[Interface\DialogFrame\UI-DialogBox-Background-Dark]],
edgeFile = [[Interface\DialogFrame\UI-DialogBox-Border]],
tile = true,
tileSize = 32,
edgeSize = 32,
insets = { left = 11, right = 11, top = 11, bottom = 11 },
})
else
local border = CreateFrame("Frame", nil, frame, "DialogBorderDarkTemplate")
border:SetAllPoints(frame)
end
 
local text = frame:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
text:SetSize(290, 0)
text:SetPoint("TOP", 0, -16)
frame.text = text
 
local function newButton(text)
local button = CreateFrame("Button", nil, frame)
button:SetSize(128, 21)
button:SetNormalFontObject(GameFontNormal)
button:SetHighlightFontObject(GameFontHighlight)
button:SetNormalTexture(130763) -- "Interface\\Buttons\\UI-DialogBox-Button-Up"
button:GetNormalTexture():SetTexCoord(0.0, 1.0, 0.0, 0.71875)
button:SetPushedTexture(130761) -- "Interface\\Buttons\\UI-DialogBox-Button-Down"
button:GetPushedTexture():SetTexCoord(0.0, 1.0, 0.0, 0.71875)
button:SetHighlightTexture(130762) -- "Interface\\Buttons\\UI-DialogBox-Button-Highlight"
button:GetHighlightTexture():SetTexCoord(0.0, 1.0, 0.0, 0.71875)
button:SetText(text)
return button
end
 
local accept = newButton(ACCEPT)
accept:SetPoint("BOTTOMRIGHT", frame, "BOTTOM", -6, 16)
frame.accept = accept
 
local cancel = newButton(CANCEL)
cancel:SetPoint("LEFT", accept, "RIGHT", 13, 0)
frame.cancel = cancel
end
end
local function confirmPopup(appName, rootframe, basepath, info, message, func, ...)
if not StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"] then
StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"] = {}
end
local t = StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"]
for k in pairs(t) do
t[k] = nil
end
t.text = message
t.button1 = ACCEPT
t.button2 = CANCEL
t.preferredIndex = STATICPOPUP_NUMDIALOGS
local dialog, oldstrata
t.OnAccept = function()
safecall(func, unpack(t))
if dialog and oldstrata then
dialog:SetFrameStrata(oldstrata)
end
local frame = AceConfigDialog.popup
frame:Show()
frame.text:SetText(message)
-- From StaticPopup.lua
-- local height = 32 + text:GetHeight() + 2;
-- height = height + 6 + accept:GetHeight()
-- We add 32 + 2 + 6 + 21 (button height) == 61
local height = 61 + frame.text:GetHeight()
frame:SetHeight(height)
 
frame.accept:ClearAllPoints()
frame.accept:SetPoint("BOTTOMRIGHT", frame, "BOTTOM", -6, 16)
frame.cancel:Show()
 
local t = {...}
local tCount = select("#", ...)
frame.accept:SetScript("OnClick", function(self)
safecall(func, unpack(t, 1, tCount)) -- Manually set count as unpack() stops on nil (bug with #table)
AceConfigDialog:Open(appName, rootframe, unpack(basepath or emptyTbl))
frame:Hide()
self:SetScript("OnClick", nil)
frame.cancel:SetScript("OnClick", nil)
del(info)
end
t.OnCancel = function()
if dialog and oldstrata then
dialog:SetFrameStrata(oldstrata)
end
end)
frame.cancel:SetScript("OnClick", function(self)
AceConfigDialog:Open(appName, rootframe, unpack(basepath or emptyTbl))
frame:Hide()
self:SetScript("OnClick", nil)
frame.accept:SetScript("OnClick", nil)
del(info)
end
for i = 1, select("#", ...) do
t[i] = select(i, ...) or false
end
t.timeout = 0
t.whileDead = 1
t.hideOnEscape = 1
 
dialog = StaticPopup_Show("ACECONFIGDIALOG30_CONFIRM_DIALOG")
if dialog then
oldstrata = dialog:GetFrameStrata()
dialog:SetFrameStrata("TOOLTIP")
end
end)
end
 
local function validationErrorPopup(message)
if not StaticPopupDialogs["ACECONFIGDIALOG30_VALIDATION_ERROR_DIALOG"] then
StaticPopupDialogs["ACECONFIGDIALOG30_VALIDATION_ERROR_DIALOG"] = {}
end
local t = StaticPopupDialogs["ACECONFIGDIALOG30_VALIDATION_ERROR_DIALOG"]
t.text = message
t.button1 = OKAY
t.preferredIndex = STATICPOPUP_NUMDIALOGS
local dialog, oldstrata
t.OnAccept = function()
if dialog and oldstrata then
dialog:SetFrameStrata(oldstrata)
end
end
t.timeout = 0
t.whileDead = 1
t.hideOnEscape = 1
local frame = AceConfigDialog.popup
frame:Show()
frame.text:SetText(message)
-- From StaticPopup.lua
-- local height = 32 + text:GetHeight() + 2;
-- height = height + 6 + accept:GetHeight()
-- We add 32 + 2 + 6 + 21 (button height) == 61
local height = 61 + frame.text:GetHeight()
frame:SetHeight(height)
 
dialog = StaticPopup_Show("ACECONFIGDIALOG30_VALIDATION_ERROR_DIALOG")
if dialog then
oldstrata = dialog:GetFrameStrata()
dialog:SetFrameStrata("TOOLTIP")
end
frame.accept:ClearAllPoints()
frame.accept:SetPoint("BOTTOM", frame, "BOTTOM", 0, 16)
frame.cancel:Hide()
 
frame.accept:SetScript("OnClick", function()
frame:Hide()
end)
end
 
local function ActivateControl(widget, event, ...)
704,7 → 729,7
end
end
end
 
 
local success
if validated and option.type ~= "execute" then
if type(validate) == "string" then
719,7 → 744,7
if not success then validated = false end
end
end
 
 
local rootframe = user.rootframe
if not validated or type(validated) == "string" then
if not validated then
744,7 → 769,7
del(info)
return true
else
 
 
local confirmText = option.confirmText
--call confirm func/method
if type(confirm) == "string" then
785,10 → 810,10
confirmText = confirmText.." - "..desc
end
end
 
 
local iscustom = user.rootframe:GetUserData("iscustom")
local rootframe
 
 
if iscustom then
rootframe = user.rootframe
end
825,7 → 850,7
--full refresh of the frame, some controls dont cause this on all events
if option.type == "color" then
if event == "OnValueConfirmed" then
 
 
if iscustom then
AceConfigDialog:Open(user.appName, user.rootframe, unpack(basepath))
else
886,7 → 911,7
 
local function MultiControlOnClosed(widget, event, ...)
local user = widget:GetUserDataTable()
if user.valuechanged then
if user.valuechanged and not widget:IsReleasing() then
local iscustom = user.rootframe:GetUserData("iscustom")
local basepath = user.rootframe:GetUserData("basepath") or emptyTbl
if iscustom then
1064,7 → 1089,24
control:SetCallback("OnEnter", OptionOnMouseOver)
end
 
local function CreateControl(userControlType, fallbackControlType)
local control
if userControlType then
control = gui:Create(userControlType)
if not control then
geterrorhandler()(("Invalid Custom Control Type - %s"):format(tostring(userControlType)))
end
end
if not control then
control = gui:Create(fallbackControlType)
end
return control
end
 
local function sortTblAsStrings(x,y)
return tostring(x) < tostring(y) -- Support numbers as keys
end
 
--[[
options - root of the options table being fed
container - widget that controls will be placed in
1095,7 → 1137,7
else
GroupContainer = gui:Create("SimpleGroup")
end
 
 
GroupContainer.width = "fill"
GroupContainer:SetLayout("flow")
container:AddChild(GroupContainer)
1104,16 → 1146,17
else
--Control to feed
local control
 
 
local name = GetOptionsMemberValue("name", v, options, path, appName)
 
 
if v.type == "execute" then
 
 
local imageCoords = GetOptionsMemberValue("imageCoords",v, options, path, appName)
local image, width, height = GetOptionsMemberValue("image",v, options, path, appName)
 
if type(image) == "string" or type(image) == "number" then
control = gui:Create("Icon")
 
local iconControl = type(image) == "string" or type(image) == "number"
control = CreateControl(v.dialogControl or v.control, iconControl and "Icon" or "Button")
if iconControl then
if not width then
width = GetOptionsMemberValue("imageWidth",v, options, path, appName)
end
1134,19 → 1177,13
control:SetImageSize(width, height)
control:SetLabel(name)
else
control = gui:Create("Button")
control:SetText(name)
end
control:SetCallback("OnClick",ActivateControl)
 
elseif v.type == "input" then
local controlType = v.dialogControl or v.control or (v.multiline and "MultiLineEditBox") or "EditBox"
control = gui:Create(controlType)
if not control then
geterrorhandler()(("Invalid Custom Control Type - %s"):format(tostring(controlType)))
control = gui:Create(v.multiline and "MultiLineEditBox" or "EditBox")
end
 
control = CreateControl(v.dialogControl or v.control, v.multiline and "MultiLineEditBox" or "EditBox")
 
if v.multiline and control.SetNumLines then
control:SetNumLines(tonumber(v.multiline) or 4)
end
1159,21 → 1196,21
control:SetText(text)
 
elseif v.type == "toggle" then
control = gui:Create("CheckBox")
control = CreateControl(v.dialogControl or v.control, "CheckBox")
control:SetLabel(name)
control:SetTriState(v.tristate)
local value = GetOptionsMemberValue("get",v, options, path, appName)
control:SetValue(value)
control:SetCallback("OnValueChanged",ActivateControl)
 
 
if v.descStyle == "inline" then
local desc = GetOptionsMemberValue("desc", v, options, path, appName)
control:SetDescription(desc)
end
 
 
local image = GetOptionsMemberValue("image", v, options, path, appName)
local imageCoords = GetOptionsMemberValue("imageCoords", v, options, path, appName)
 
 
if type(image) == "string" or type(image) == "number" then
if type(imageCoords) == "table" then
control:SetImage(image, unpack(imageCoords))
1182,7 → 1219,7
end
end
elseif v.type == "range" then
control = gui:Create("Slider")
control = CreateControl(v.dialogControl or v.control, "Slider")
control:SetLabel(name)
control:SetSliderValues(v.softMin or v.min or 0, v.softMax or v.max or 100, v.bigStep or v.step or 0)
control:SetIsPercent(v.isPercent)
1196,6 → 1233,7
 
elseif v.type == "select" then
local values = GetOptionsMemberValue("values", v, options, path, appName)
local sorting = GetOptionsMemberValue("sorting", v, options, path, appName)
if v.style == "radio" then
local disabled = CheckOptionDisabled(v, options, path, appName)
local width = GetOptionsMemberValue("width",v,options,path,appName)
1206,12 → 1244,14
 
control:PauseLayout()
local optionValue = GetOptionsMemberValue("get",v, options, path, appName)
local t = {}
for value, text in pairs(values) do
t[#t+1]=value
if not sorting then
sorting = {}
for value, text in pairs(values) do
sorting[#sorting+1]=value
end
tsort(sorting, sortTblAsStrings)
end
tsort(t)
for k, value in ipairs(t) do
for k, value in ipairs(sorting) do
local text = values[value]
local radio = gui:Create("CheckBox")
radio:SetLabel(text)
1238,19 → 1278,14
control:ResumeLayout()
control:DoLayout()
else
local controlType = v.dialogControl or v.control or "Dropdown"
control = gui:Create(controlType)
if not control then
geterrorhandler()(("Invalid Custom Control Type - %s"):format(tostring(controlType)))
control = gui:Create("Dropdown")
end
control = CreateControl(v.dialogControl or v.control, "Dropdown")
local itemType = v.itemControl
if itemType and not gui:GetWidgetVersion(itemType) then
geterrorhandler()(("Invalid Custom Item Type - %s"):format(tostring(itemType)))
itemType = nil
end
control:SetLabel(name)
control:SetList(values, nil, itemType)
control:SetList(values, sorting, itemType)
local value = GetOptionsMemberValue("get",v, options, path, appName)
if not values[value] then
value = nil
1262,9 → 1297,7
elseif v.type == "multiselect" then
local values = GetOptionsMemberValue("values", v, options, path, appName)
local disabled = CheckOptionDisabled(v, options, path, appName)
 
local controlType = v.dialogControl or v.control
 
 
local valuesort = new()
if values then
for value, text in pairs(values) do
1272,7 → 1305,8
end
end
tsort(valuesort)
 
 
local controlType = v.dialogControl or v.control
if controlType then
control = gui:Create(controlType)
if not control then
1340,13 → 1374,13
control:ResumeLayout()
control:DoLayout()
 
 
 
end
 
 
del(valuesort)
 
elseif v.type == "color" then
control = gui:Create("ColorPicker")
control = CreateControl(v.dialogControl or v.control, "ColorPicker")
control:SetLabel(name)
control:SetHasAlpha(GetOptionsMemberValue("hasAlpha",v, options, path, appName))
control:SetColor(GetOptionsMemberValue("get",v, options, path, appName))
1354,20 → 1388,20
control:SetCallback("OnValueConfirmed",ActivateControl)
 
elseif v.type == "keybinding" then
control = gui:Create("Keybinding")
control = CreateControl(v.dialogControl or v.control, "Keybinding")
control:SetLabel(name)
control:SetKey(GetOptionsMemberValue("get",v, options, path, appName))
control:SetCallback("OnKeyChanged",ActivateControl)
 
elseif v.type == "header" then
control = gui:Create("Heading")
control = CreateControl(v.dialogControl or v.control, "Heading")
control:SetText(name)
control.width = "fill"
 
elseif v.type == "description" then
control = gui:Create("Label")
control = CreateControl(v.dialogControl or v.control, "Label")
control:SetText(name)
 
 
local fontSize = GetOptionsMemberValue("fontSize",v, options, path, appName)
if fontSize == "medium" then
control:SetFontObject(GameFontHighlight)
1376,10 → 1410,10
else -- small or invalid
control:SetFontObject(GameFontHighlightSmall)
end
 
 
local imageCoords = GetOptionsMemberValue("imageCoords",v, options, path, appName)
local image, width, height = GetOptionsMemberValue("image",v, options, path, appName)
 
 
if type(image) == "string" or type(image) == "number" then
if not width then
width = GetOptionsMemberValue("imageWidth",v, options, path, appName)
1428,7 → 1462,7
InjectInfo(control, options, v, path, rootframe, appName)
container:AddChild(control)
end
 
 
end
end
tremove(path)
1453,7 → 1487,8
local option = user.option
local path = user.path
local appName = user.appName
 
local tooltip = AceConfigDialog.tooltip
 
local feedpath = new()
for i = 1, #path do
feedpath[i] = path[i]
1468,49 → 1503,50
 
local name = GetOptionsMemberValue("name", group, options, feedpath, appName)
local desc = GetOptionsMemberValue("desc", group, options, feedpath, appName)
 
GameTooltip:SetOwner(button, "ANCHOR_NONE")
 
tooltip:SetOwner(button, "ANCHOR_NONE")
tooltip:ClearAllPoints()
if widget.type == "TabGroup" then
GameTooltip:SetPoint("BOTTOM",button,"TOP")
tooltip:SetPoint("BOTTOM",button,"TOP")
else
GameTooltip:SetPoint("LEFT",button,"RIGHT")
tooltip:SetPoint("LEFT",button,"RIGHT")
end
 
GameTooltip:SetText(name, 1, .82, 0, true)
 
tooltip:SetText(name, 1, .82, 0, true)
 
if type(desc) == "string" then
GameTooltip:AddLine(desc, 1, 1, 1, true)
tooltip:AddLine(desc, 1, 1, 1, true)
end
 
GameTooltip:Show()
 
tooltip:Show()
end
 
local function TreeOnButtonLeave(widget, event, value, button)
GameTooltip:Hide()
AceConfigDialog.tooltip:Hide()
end
 
 
local function GroupExists(appName, options, path, uniquevalue)
if not uniquevalue then return false end
 
 
local feedpath = new()
local temppath = new()
for i = 1, #path do
feedpath[i] = path[i]
end
 
 
BuildPath(feedpath, ("\001"):split(uniquevalue))
 
 
local group = options
for i = 1, #feedpath do
local v = feedpath[i]
temppath[i] = v
group = GetSubOption(group, v)
 
if not group or group.type ~= "group" or CheckOptionHidden(group, options, temppath, appName) then
 
if not group or group.type ~= "group" or CheckOptionHidden(group, options, temppath, appName) then
del(feedpath)
del(temppath)
return false
return false
end
end
del(feedpath)
1533,10 → 1569,6
end
 
BuildPath(feedpath, ("\001"):split(uniquevalue))
local group = options
for i = 1, #feedpath do
group = GetSubOption(group, feedpath[i])
end
widget:ReleaseChildren()
AceConfigDialog:FeedGroup(user.appName,options,widget,rootframe,feedpath)
 
1633,7 → 1665,7
tab:SetCallback("OnGroupSelected", GroupSelected)
tab:SetCallback("OnTabEnter", TreeOnButtonEnter)
tab:SetCallback("OnTabLeave", TreeOnButtonLeave)
 
 
local status = AceConfigDialog:GetStatusTable(appName, path)
if not status.groups then
status.groups = {}
1653,7 → 1685,7
break
end
end
 
 
container:AddChild(tab)
 
elseif grouptype == "select" then
1676,7 → 1708,7
if firstgroup then
select:SetGroup((GroupExists(appName, options, path,status.groups.selected) and status.groups.selected) or firstgroup)
end
 
 
select.width = "fill"
select.height = "fill"
 
1688,14 → 1720,14
local tree = gui:Create("TreeGroup")
InjectInfo(tree, options, group, path, rootframe, appName)
tree:EnableButtonTooltips(false)
 
 
tree.width = "fill"
tree.height = "fill"
 
tree:SetCallback("OnGroupSelected", GroupSelected)
tree:SetCallback("OnButtonEnter", TreeOnButtonEnter)
tree:SetCallback("OnButtonLeave", TreeOnButtonLeave)
 
 
local status = AceConfigDialog:GetStatusTable(appName, path)
if not status.groups then
status.groups = {}
1736,7 → 1768,7
end
this.closing[appName] = nil
end
 
 
if this.closeAll then
for k, v in pairs(AceConfigDialog.OpenFrames) do
if not this.closeAllOverride[k] then
1746,7 → 1778,7
this.closeAll = nil
wipe(this.closeAllOverride)
end
 
 
for appName in pairs(this.apps) do
if AceConfigDialog.OpenFrames[appName] then
local user = AceConfigDialog.OpenFrames[appName]:GetUserDataTable()
1831,10 → 1863,10
local options = app("dialog", MAJOR)
 
local f
 
 
local path = new()
local name = GetOptionsMemberValue("name", options, options, path, appName)
 
 
--If an optional path is specified add it to the path table before feeding the options
--as container is optional as well it may contain the first element of the path
if type(container) == "string" then
1844,7 → 1876,7
for n = 1, select("#",...) do
tinsert(path, (select(n, ...)))
end
 
 
local option = options
if type(container) == "table" and container.type == "BlizOptionsGroup" and #path > 0 then
for i = 1, #path do
1852,7 → 1884,7
end
name = format("%s - %s", name, GetOptionsMemberValue("name", option, options, path, appName))
end
 
 
--if a container is given feed into that
if container then
f = container
1946,19 → 1978,19
-- @param name A descriptive name to display in the options tree (defaults to appName)
-- @param parent The parent to use in the interface options tree.
-- @param ... The path in the options table to feed into the interface options panel.
-- @return The reference to the frame registered into the Interface Options.
-- @return The reference to the frame registered into the Interface Options.
function AceConfigDialog:AddToBlizOptions(appName, name, parent, ...)
local BlizOptions = AceConfigDialog.BlizOptions
 
 
local key = appName
for n = 1, select("#", ...) do
key = key.."\001"..select(n, ...)
end
 
 
if not BlizOptions[appName] then
BlizOptions[appName] = {}
end
 
 
if not BlizOptions[appName][key] then
local group = gui:Create("BlizOptionsGroup")
BlizOptions[appName][key] = group
AceConfigCmd-3.0/AceConfigCmd-3.0.lua
1,7 → 1,7
--- AceConfigCmd-3.0 handles access to an options table through the "command line" interface via the ChatFrames.
-- @class file
-- @name AceConfigCmd-3.0
-- @release $Id: AceConfigCmd-3.0.lua 1161 2017-08-12 14:30:16Z funkydude $
-- @release $Id: AceConfigCmd-3.0.lua 1202 2019-05-15 23:11:22Z nevcairiel $
 
--[[
AceConfigCmd-3.0
63,7 → 63,7
 
-- pickfirstset() - picks the first non-nil value and returns it
 
local function pickfirstset(...)
local function pickfirstset(...)
for i=1,select("#",...) do
if select(i,...)~=nil then
return select(i,...)
120,7 → 120,7
info.arg = tab.arg
info.option = tab
info.type = tab.type
 
 
if type(method)=="function" then
return method(info, ...)
else
131,7 → 131,7
-- do_final() - do the final step (set/execute) along with validation and confirmation
 
local function do_final(info, inputpos, tab, methodtype, ...)
if info.validate then
if info.validate then
local res = callmethod(info,inputpos,tab,"validate",...)
if type(res)=="string" then
usererr(info, inputpos, "'"..strsub(info.input, inputpos).."' - "..res)
139,7 → 139,7
end
end
-- console ignores .confirm
 
 
callmethod(info,inputpos,tab,methodtype, ...)
end
 
152,8 → 152,8
if val~=nil then
if val==false then
val=nil
elseif not types[type(val)] then
err(info, inputpos, "'" .. paramname.. "' - "..errormsg)
elseif not types[type(val)] then
err(info, inputpos, "'" .. paramname.. "' - "..errormsg)
end
info[paramname] = val
info[paramname.."_at"] = depth
166,13 → 166,13
local dummytable={}
 
local function iterateargs(tab)
if not tab.plugins then
return pairs(tab.args)
if not tab.plugins then
return pairs(tab.args)
end
 
 
local argtabkey,argtab=next(tab.plugins)
local v
 
 
return function(_, k)
while argtab do
k,v = next(argtab, k)
206,18 → 206,18
if not noHead then
print("|cff33ff99"..info.appName.."|r: Arguments to |cffffff78/"..info[0].."|r "..strsub(info.input,1,inputpos-1)..":")
end
 
 
local sortTbl = {} -- [1..n]=name
local refTbl = {} -- [name]=tableref
 
 
for k,v in iterateargs(tab) do
if not refTbl[k] then -- a plugin overriding something in .args
tinsert(sortTbl, k)
refTbl[k] = v
end
end
 
tsort(sortTbl, function(one, two)
 
tsort(sortTbl, function(one, two)
local o1 = refTbl[one].order or 100
local o2 = refTbl[two].order or 100
if type(o1) == "function" or type(o1) == "string" then
240,7 → 240,7
if o1==o2 then return tostring(one)<tostring(two) end -- compare names
return o1<o2
end)
 
 
for i = 1, #sortTbl do
local k = sortTbl[i]
local v = refTbl[k]
327,7 → 327,7
return s
end
 
-- handle() - selfrecursing function that processes input->optiontable
-- handle() - selfrecursing function that processes input->optiontable
-- - depth - starts at 0
-- - retfalse - return false rather than produce error if a match is not found (used by inlined groups)
 
346,16 → 346,16
local oldfunc,oldfunc_at = getparam(info,inputpos,tab,depth,"func",functypes,funcmsg)
local oldvalidate,oldvalidate_at = getparam(info,inputpos,tab,depth,"validate",functypes,funcmsg)
--local oldconfirm,oldconfirm_at = getparam(info,inputpos,tab,depth,"confirm",functypes,funcmsg)
 
 
-------------------------------------------------------------------
-- Act according to .type of this table
 
 
if tab.type=="group" then
------------ group --------------------------------------------
 
 
if type(tab.args)~="table" then err(info, inputpos) end
if tab.plugins and type(tab.plugins)~="table" then err(info,inputpos) end
 
 
-- grab next arg from input
local _,nextpos,arg = (info.input):find(" *([^ ]+) *", inputpos)
if not arg then
363,11 → 363,11
return
end
nextpos=nextpos+1
 
 
-- loop .args and try to find a key with a matching name
for k,v in iterateargs(tab) do
if not(type(k)=="string" and type(v)=="table" and type(v.type)=="string") then err(info,inputpos, "options table child '"..tostring(k).."' is malformed") end
 
 
-- is this child an inline group? if so, traverse into it
if v.type=="group" and pickfirstset(v.cmdInline, v.inline, false) then
info[depth+1] = k
383,8 → 383,8
return handle(info,nextpos,v,depth+1)
end
end
 
-- no match
 
-- no match
if retfalse then
-- restore old infotable members and return false to indicate failure
info.handler,info.handler_at = oldhandler,oldhandler_at
395,23 → 395,23
--info.confirm,info.confirm_at = oldconfirm,oldconfirm_at
return false
end
 
 
-- couldn't find the command, display error
usererr(info, inputpos, "'"..arg.."' - " .. L["unknown argument"])
return
end
 
 
local str = strsub(info.input,inputpos);
 
 
if tab.type=="execute" then
------------ execute --------------------------------------------
do_final(info, inputpos, tab, "func")
 
 
 
 
 
elseif tab.type=="input" then
------------ input --------------------------------------------
 
 
local res = true
if tab.pattern then
if not(type(tab.pattern)=="string") then err(info, inputpos, "'pattern' - expected a string") end
420,11 → 420,11
return
end
end
 
 
do_final(info, inputpos, tab, "set", str)
 
 
 
 
 
elseif tab.type=="toggle" then
------------ toggle --------------------------------------------
local b
444,7 → 444,7
else
b = not b
end
 
 
elseif str==L["on"] then
b = true
elseif str==L["off"] then
459,10 → 459,10
end
return
end
 
 
do_final(info, inputpos, tab, "set", b)
 
 
 
elseif tab.type=="range" then
------------ range --------------------------------------------
local val = tonumber(str)
481,21 → 481,21
usererr(info, inputpos, val.." - "..format(L["must be equal to or lower than %s"], tostring(info.max)) )
return
end
 
 
do_final(info, inputpos, tab, "set", val)
 
 
 
elseif tab.type=="select" then
------------ select ------------------------------------
local str = strtrim(strlower(str))
 
 
local values = tab.values
if type(values) == "function" or type(values) == "string" then
info.values = values
values = callmethod(info, inputpos, tab, "values")
info.values = nil
end
 
 
if str == "" then
local b = callmethod(info, inputpos, tab, "get")
local fmt = "|cffffff78- [%s]|r %s"
512,7 → 512,7
end
 
local ok
for k,v in pairs(values) do
for k,v in pairs(values) do
if strlower(k)==str then
str = k -- overwrite with key (in case of case mismatches)
ok = true
523,20 → 523,20
usererr(info, inputpos, "'"..str.."' - "..L["unknown selection"])
return
end
 
 
do_final(info, inputpos, tab, "set", str)
 
 
elseif tab.type=="multiselect" then
------------ multiselect -------------------------------------------
local str = strtrim(strlower(str))
 
 
local values = tab.values
if type(values) == "function" or type(values) == "string" then
info.values = values
values = callmethod(info, inputpos, tab, "values")
info.values = nil
end
 
 
if str == "" then
local fmt = "|cffffff78- [%s]|r %s"
local fmt_sel = "|cffffff78- [%s]|r %s |cffff0000*|r"
550,7 → 550,7
end
return
end
 
 
--build a table of the selections, checking that they exist
--parse for =on =off =default in the process
--table will be key = true for options that should toggle, key = [on|off|default] for options to be set
559,25 → 559,25
--parse option=on etc
local opt, val = v:match('(.+)=(.+)')
--get option if toggling
if not opt then
opt = v
if not opt then
opt = v
end
 
 
--check that the opt is valid
local ok
for k,v in pairs(values) do
for k,v in pairs(values) do
if strlower(k)==opt then
opt = k -- overwrite with key (in case of case mismatches)
ok = true
break
end
end
 
 
if not ok then
usererr(info, inputpos, "'"..opt.."' - "..L["unknown selection"])
return
end
 
 
--check that if val was supplied it is valid
if val then
if val == L["on"] or val == L["off"] or (tab.tristate and val == L["default"]) then
596,14 → 596,14
sels[opt] = true
end
end
 
 
for opt, val in pairs(sels) do
local newval
 
 
if (val == true) then
--toggle the option
local b = callmethod(info, inputpos, tab, "get", opt)
 
 
if tab.tristate then
--cycle in true, nil, false order
if b then
627,11 → 627,11
newval = nil
end
end
 
 
do_final(info, inputpos, tab, "set", opt, newval)
end
 
 
 
 
elseif tab.type=="color" then
------------ color --------------------------------------------
local str = strtrim(strlower(str))
639,16 → 639,16
--TODO: Show current value
return
end
 
 
local r, g, b, a
 
 
local hasAlpha = tab.hasAlpha
if type(hasAlpha) == "function" or type(hasAlpha) == "string" then
info.hasAlpha = hasAlpha
hasAlpha = callmethod(info, inputpos, tab, 'hasAlpha')
info.hasAlpha = nil
end
 
 
if hasAlpha then
if str:len() == 8 and str:find("^%x*$") then
--parse a hex string
662,7 → 662,7
usererr(info, inputpos, format(L["'%s' - expected 'RRGGBBAA' or 'r g b a'."], str))
return
end
 
 
if r >= 0.0 and r <= 1.0 and g >= 0.0 and g <= 1.0 and b >= 0.0 and b <= 1.0 and a >= 0.0 and a <= 1.0 then
--values are valid
elseif r >= 0 and r <= 255 and g >= 0 and g <= 255 and b >= 0 and b <= 255 and a >= 0 and a <= 255 then
701,7 → 701,7
usererr(info, inputpos, format(L["'%s' - values must all be either in the range 0-1 or 0-255."], str))
end
end
 
 
do_final(info, inputpos, tab, "set", r,g,b,a)
 
elseif tab.type=="keybinding" then
737,7 → 737,7
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon", "AceConsole-3.0")
-- -- Use AceConsole-3.0 to register a Chat Command
-- MyAddon:RegisterChatCommand("mychat", "ChatCommand")
--
--
-- -- Show the GUI if no input is supplied, otherwise handle the chat input.
-- function MyAddon:ChatCommand(input)
-- -- Assuming "MyOptions" is the appName of a valid options table
754,7 → 754,7
error([[Usage: HandleCommand("slashcmd", "appName", "input"): 'appName' - no options table "]]..tostring(appName)..[[" has been registered]], 2)
end
local options = assert( optgetter("cmd", MAJOR) )
 
 
local info = { -- Don't try to recycle this, it gets handed off to callbacks and whatnot
[0] = slashcmd,
appName = appName,
765,7 → 765,7
uiType = "cmd",
uiName = MAJOR,
}
 
 
handle(info, 1, options, 0) -- (info, inputpos, table, depth)
end