@ -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 1 169 2018-02-27 16:18:28Z nevcairiel $
-- @release $Id: AceConfigDialog-3.0.lua 1 248 2021-02-05 14:27:49Z funkehdude $
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 " , 81
local AceConfigDialog , oldminor = LibStub : NewLibrary ( MAJOR , MINOR )
if not AceConfigDialog then return end
@ -15,22 +15,23 @@ if not AceConfigDialog then return end
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 t concat, t insert, tsort , tremove , tsort = table.concat , table.insert , table.sort , table.remove , table.sort
local t insert, tsort , tremove , wipe = table.insert , table.sort , table.remove , table.wipe
local strmatch , format = string.match , string.format
local assert, loadstring , error = assert , loadstring , error
local pairs , next , select , type , unpack , wipe, ipairs = pairs , next , select , type , unpack , wipe , ipairs
local rawset, tostring, tonumber = rawset , tostring , tonumber
local error = error
local pairs , next , select , type , unpack , ipairs = pairs , next , select , type , unpack , ipairs
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 @@ local function errorhandler(err)
return geterrorhandler ( ) ( err )
end
local function CreateDispatcher ( argCount )
local code = [ [
local xpcall , eh = ...
local method , ARGS
local function call ( ) return method ( ARGS ) end
local function dispatch ( func , ... )
method = func
if not method then return end
ARGS = ...
return xpcall ( call , eh )
end
return dispatch
] ]
local ARGS = { }
for i = 1 , argCount do ARGS [ i ] = " arg " .. i end
code = code : gsub ( " ARGS " , tconcat ( ARGS , " , " ) )
return assert ( loadstring ( code , " safecall Dispatcher[ " .. argCount .. " ] " ) ) ( xpcall , errorhandler )
end
local Dispatchers = setmetatable ( { } , { __index = function ( self , argCount )
local dispatcher = CreateDispatcher ( argCount )
rawset ( self , argCount , dispatcher )
return dispatcher
end } )
Dispatchers [ 0 ] = function ( func )
return xpcall ( func , errorhandler )
end
local function safecall ( func , ... )
return Dispatchers [ select ( " # " , ... ) ] ( func , ... )
if func then
return xpcall ( func , errorhandler , ... )
end
end
local width_multiplier = 170
@ -85,18 +57,18 @@ local width_multiplier = 170
--[[
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 allIsLiteral = {
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 @@ local function GetOptionsMemberValue(membername, option, options, path, appName,
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 function GetOptionsMemberValue(membername, option, options, path, appName,
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 @@ local function GetOptionsMemberValue(membername, option, options, path, appName,
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 @@ local function GetOptionsMemberValue(membername, option, options, path, appName,
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 @@ local function compareOptions(a,b)
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 @@ end
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 @@ local function BuildSortedOptionsTable(group, keySort, opts, options, path, appN
end
end
end
for k , v in pairs ( group.args ) do
if not opts [ k ] then
tinsert ( keySort , k )
@ -391,7 +363,7 @@ local function DelTree(tree)
end
local function CleanUserData ( widget , event )
local user = widget : GetUserDataTable ( )
if user.path then
@ -431,7 +403,7 @@ end
-- - 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 @@ end
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 @@ function AceConfigDialog:SelectGroup(appName, ...)
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 @@ function AceConfigDialog:SelectGroup(appName, ...)
--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 @@ function AceConfigDialog:SelectGroup(appName, ...)
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 function OptionOnMouseOver(widget, event)
local options = user.options
local path = user.path
local appName = user.appName
local tooltip = AceConfigDialog.tooltip
GameT ooltip: SetOwner ( widget.frame , " ANCHOR_TOPRIGHT " )
t ooltip: 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
GameT ooltip: SetText ( name , 1 , .82 , 0 , true )
t ooltip: SetText ( name , 1 , .82 , 0 , true )
if opt.type == " multiselect " then
GameT ooltip: AddLine ( user.text , 0.5 , 0.5 , 0.8 , true )
end
t ooltip: AddLine ( user.text , 0.5 , 0.5 , 0.8 , true )
end
if type ( desc ) == " string " then
GameT ooltip: AddLine ( desc , 1 , 1 , 1 , true )
t ooltip: AddLine ( desc , 1 , 1 , 1 , true )
end
if type ( usage ) == " string " then
GameT ooltip: AddLine ( " Usage: " .. usage , NORMAL_FONT_COLOR.r , NORMAL_FONT_COLOR.g , NORMAL_FONT_COLOR.b , true )
t ooltip: AddLine ( " Usage: " .. usage , NORMAL_FONT_COLOR.r , NORMAL_FONT_COLOR.g , NORMAL_FONT_COLOR.b , true )
end
GameT ooltip: Show ( )
t ooltip: Show ( )
end
local function OptionOnMouseLeave ( widget , event )
GameT ooltip: Hide ( )
AceConfigDialog.t ooltip: Hide ( )
end
local function GetFuncName ( option )
@ -569,71 +542,127 @@ local function GetFuncName(option)
return " set "
end
end
do
local frame = AceConfigDialog.popup
if not frame or oldminor < 81 then
frame = CreateFrame ( " Frame " , nil , UIParent )
AceConfigDialog.popup = frame
frame : Hide ( )
frame : SetPoint ( " CENTER " , UIParent , " CENTER " )
frame : SetSize ( 320 , 72 )
frame : EnableMouse ( true ) -- Do not allow click-through on the frame
frame : SetFrameStrata ( " TOOLTIP " )
frame : SetFrameLevel ( 100 ) -- Lots of room to draw under it
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 not frame.SetFixedFrameStrata then -- API capability check (classic check)
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 , " DialogBorderOpaqueTemplate " )
border : SetAllPoints ( frame )
frame : SetFixedFrameStrata ( true )
frame : SetFixedFrameLevel ( true )
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
dialog = StaticPopup_Show ( " ACECONFIGDIALOG30_VALIDATION_ERROR_DIALOG " )
if dialog then
oldstrata = dialog : GetFrameStrata ( )
dialog : SetFrameStrata ( " TOOLTIP " )
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 ( " BOTTOM " , frame , " BOTTOM " , 0 , 16 )
frame.cancel : Hide ( )
frame.accept : SetScript ( " OnClick " , function ( )
frame : Hide ( )
end )
end
local function ActivateControl ( widget , event , ... )
@ -704,7 +733,7 @@ local function ActivateControl(widget, event, ...)
end
end
end
local success
if validated and option.type ~= " execute " then
if type ( validate ) == " string " then
@ -719,7 +748,7 @@ local function ActivateControl(widget, event, ...)
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 +773,7 @@ local function ActivateControl(widget, event, ...)
del ( info )
return true
else
local confirmText = option.confirmText
--call confirm func/method
if type ( confirm ) == " string " then
@ -785,10 +814,10 @@ local function ActivateControl(widget, event, ...)
confirmText = confirmText .. " - " .. desc
end
end
local iscustom = user.rootframe : GetUserData ( " iscustom " )
local rootframe
if iscustom then
rootframe = user.rootframe
end
@ -825,7 +854,7 @@ local function ActivateControl(widget, event, ...)
--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 +915,7 @@ end
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,6 +1093,23 @@ local function InjectInfo(control, options, option, path, rootframe, appName)
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
@ -1095,7 +1141,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
else
GroupContainer = gui : Create ( " SimpleGroup " )
end
GroupContainer.width = " fill "
GroupContainer : SetLayout ( " flow " )
container : AddChild ( GroupContainer )
@ -1104,16 +1150,17 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
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 +1181,13 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
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 +1200,21 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
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 +1223,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
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 +1237,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
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 +1248,14 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
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 +1282,14 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
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 +1301,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
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 +1309,8 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
end
end
tsort ( valuesort )
local controlType = v.dialogControl or v.control
if controlType then
control = gui : Create ( controlType )
if not control then
@ -1340,13 +1378,13 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
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 +1392,20 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
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 +1414,10 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
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 +1466,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
InjectInfo ( control , options , v , path , rootframe , appName )
container : AddChild ( control )
end
end
end
tremove ( path )
@ -1453,7 +1491,8 @@ local function TreeOnButtonEnter(widget, event, uniquevalue, button)
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 +1507,50 @@ local function TreeOnButtonEnter(widget, event, uniquevalue, button)
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
GameT ooltip: SetPoint ( " BOTTOM " , button , " TOP " )
t ooltip: SetPoint ( " BOTTOM " , button , " TOP " )
else
GameT ooltip: SetPoint ( " LEFT " , button , " RIGHT " )
t ooltip: SetPoint ( " LEFT " , button , " RIGHT " )
end
GameT ooltip: SetText ( name , 1 , .82 , 0 , true )
t ooltip: SetText ( name , 1 , .82 , 0 , true )
if type ( desc ) == " string " then
GameT ooltip: AddLine ( desc , 1 , 1 , 1 , true )
t ooltip: AddLine ( desc , 1 , 1 , 1 , true )
end
GameT ooltip: Show ( )
t ooltip: Show ( )
end
local function TreeOnButtonLeave ( widget , event , value , button )
GameT ooltip: Hide ( )
AceConfigDialog.t ooltip: 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 +1573,6 @@ local function GroupSelected(widget, event, uniquevalue)
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 +1669,7 @@ function AceConfigDialog:FeedGroup(appName,options,container,rootframe,path, isR
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 +1689,7 @@ function AceConfigDialog:FeedGroup(appName,options,container,rootframe,path, isR
break
end
end
container : AddChild ( tab )
elseif grouptype == " select " then
@ -1676,7 +1712,7 @@ function AceConfigDialog:FeedGroup(appName,options,container,rootframe,path, isR
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 +1724,14 @@ function AceConfigDialog:FeedGroup(appName,options,container,rootframe,path, isR
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 +1772,7 @@ local function RefreshOnUpdate(this)
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 +1782,7 @@ local function RefreshOnUpdate(this)
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 +1867,10 @@ function AceConfigDialog:Open(appName, container, ...)
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 +1880,7 @@ function AceConfigDialog:Open(appName, container, ...)
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 +1888,7 @@ function AceConfigDialog:Open(appName, container, ...)
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 +1982,19 @@ end
-- @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