annotate Libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua @ 6:f10c8a083d2a

The ALPHA help request popup should pop when the addon is enabled for every 15th time. I really would like some data to. The timer to start opening mail when you open the mailbox will now use the initial mail opening delay.
author Zerotorescue
date Wed, 08 Sep 2010 00:48:37 +0200
parents 823e33465b6e
children
rev   line source
Zerotorescue@0 1 --- AceConfigDialog-3.0 generates AceGUI-3.0 based windows based on option tables.
Zerotorescue@0 2 -- @class file
Zerotorescue@0 3 -- @name AceConfigDialog-3.0
Zerotorescue@0 4 -- @release $Id: AceConfigDialog-3.0.lua 958 2010-07-03 10:22:29Z nevcairiel $
Zerotorescue@0 5
Zerotorescue@0 6 local LibStub = LibStub
Zerotorescue@0 7 local MAJOR, MINOR = "AceConfigDialog-3.0", 49
Zerotorescue@0 8 local AceConfigDialog, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
Zerotorescue@0 9
Zerotorescue@0 10 if not AceConfigDialog then return end
Zerotorescue@0 11
Zerotorescue@0 12 AceConfigDialog.OpenFrames = AceConfigDialog.OpenFrames or {}
Zerotorescue@0 13 AceConfigDialog.Status = AceConfigDialog.Status or {}
Zerotorescue@0 14 AceConfigDialog.frame = AceConfigDialog.frame or CreateFrame("Frame")
Zerotorescue@0 15
Zerotorescue@0 16 AceConfigDialog.frame.apps = AceConfigDialog.frame.apps or {}
Zerotorescue@0 17 AceConfigDialog.frame.closing = AceConfigDialog.frame.closing or {}
Zerotorescue@0 18 AceConfigDialog.frame.closeAllOverride = AceConfigDialog.frame.closeAllOverride or {}
Zerotorescue@0 19
Zerotorescue@0 20 local gui = LibStub("AceGUI-3.0")
Zerotorescue@0 21 local reg = LibStub("AceConfigRegistry-3.0")
Zerotorescue@0 22
Zerotorescue@0 23 -- Lua APIs
Zerotorescue@0 24 local tconcat, tinsert, tsort, tremove = table.concat, table.insert, table.sort, table.remove
Zerotorescue@0 25 local strmatch, format = string.match, string.format
Zerotorescue@0 26 local assert, loadstring, error = assert, loadstring, error
Zerotorescue@0 27 local pairs, next, select, type, unpack, wipe = pairs, next, select, type, unpack, wipe
Zerotorescue@0 28 local rawset, tostring, tonumber = rawset, tostring, tonumber
Zerotorescue@0 29 local math_min, math_max, math_floor = math.min, math.max, math.floor
Zerotorescue@0 30
Zerotorescue@0 31 -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
Zerotorescue@0 32 -- List them here for Mikk's FindGlobals script
Zerotorescue@0 33 -- GLOBALS: NORMAL_FONT_COLOR, GameTooltip, StaticPopupDialogs, ACCEPT, CANCEL, StaticPopup_Show
Zerotorescue@0 34 -- GLOBALS: PlaySound, GameFontHighlight, GameFontHighlightSmall, GameFontHighlightLarge
Zerotorescue@0 35 -- GLOBALS: CloseSpecialWindows, InterfaceOptions_AddCategory, geterrorhandler
Zerotorescue@0 36
Zerotorescue@0 37 local emptyTbl = {}
Zerotorescue@0 38
Zerotorescue@0 39 --[[
Zerotorescue@0 40 xpcall safecall implementation
Zerotorescue@0 41 ]]
Zerotorescue@0 42 local xpcall = xpcall
Zerotorescue@0 43
Zerotorescue@0 44 local function errorhandler(err)
Zerotorescue@0 45 return geterrorhandler()(err)
Zerotorescue@0 46 end
Zerotorescue@0 47
Zerotorescue@0 48 local function CreateDispatcher(argCount)
Zerotorescue@0 49 local code = [[
Zerotorescue@0 50 local xpcall, eh = ...
Zerotorescue@0 51 local method, ARGS
Zerotorescue@0 52 local function call() return method(ARGS) end
Zerotorescue@0 53
Zerotorescue@0 54 local function dispatch(func, ...)
Zerotorescue@0 55 method = func
Zerotorescue@0 56 if not method then return end
Zerotorescue@0 57 ARGS = ...
Zerotorescue@0 58 return xpcall(call, eh)
Zerotorescue@0 59 end
Zerotorescue@0 60
Zerotorescue@0 61 return dispatch
Zerotorescue@0 62 ]]
Zerotorescue@0 63
Zerotorescue@0 64 local ARGS = {}
Zerotorescue@0 65 for i = 1, argCount do ARGS[i] = "arg"..i end
Zerotorescue@0 66 code = code:gsub("ARGS", tconcat(ARGS, ", "))
Zerotorescue@0 67 return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
Zerotorescue@0 68 end
Zerotorescue@0 69
Zerotorescue@0 70 local Dispatchers = setmetatable({}, {__index=function(self, argCount)
Zerotorescue@0 71 local dispatcher = CreateDispatcher(argCount)
Zerotorescue@0 72 rawset(self, argCount, dispatcher)
Zerotorescue@0 73 return dispatcher
Zerotorescue@0 74 end})
Zerotorescue@0 75 Dispatchers[0] = function(func)
Zerotorescue@0 76 return xpcall(func, errorhandler)
Zerotorescue@0 77 end
Zerotorescue@0 78
Zerotorescue@0 79 local function safecall(func, ...)
Zerotorescue@0 80 return Dispatchers[select("#", ...)](func, ...)
Zerotorescue@0 81 end
Zerotorescue@0 82
Zerotorescue@0 83 local width_multiplier = 170
Zerotorescue@0 84
Zerotorescue@0 85 --[[
Zerotorescue@0 86 Group Types
Zerotorescue@0 87 Tree - All Descendant Groups will all become nodes on the tree, direct child options will appear above the tree
Zerotorescue@0 88 - Descendant Groups with inline=true and thier children will not become nodes
Zerotorescue@0 89
Zerotorescue@0 90 Tab - Direct Child Groups will become tabs, direct child options will appear above the tab control
Zerotorescue@0 91 - Grandchild groups will default to inline unless specified otherwise
Zerotorescue@0 92
Zerotorescue@0 93 Select- Same as Tab but with entries in a dropdown rather than tabs
Zerotorescue@0 94
Zerotorescue@0 95
Zerotorescue@0 96 Inline Groups
Zerotorescue@0 97 - Will not become nodes of a select group, they will be effectivly part of thier parent group seperated by a border
Zerotorescue@0 98 - If declared on a direct child of a root node of a select group, they will appear above the group container control
Zerotorescue@0 99 - When a group is displayed inline, all descendants will also be inline members of the group
Zerotorescue@0 100
Zerotorescue@0 101 ]]
Zerotorescue@0 102
Zerotorescue@0 103 -- Recycling functions
Zerotorescue@0 104 local new, del, copy
Zerotorescue@0 105 --newcount, delcount,createdcount,cached = 0,0,0
Zerotorescue@0 106 do
Zerotorescue@0 107 local pool = setmetatable({},{__mode="k"})
Zerotorescue@0 108 function new()
Zerotorescue@0 109 --newcount = newcount + 1
Zerotorescue@0 110 local t = next(pool)
Zerotorescue@0 111 if t then
Zerotorescue@0 112 pool[t] = nil
Zerotorescue@0 113 return t
Zerotorescue@0 114 else
Zerotorescue@0 115 --createdcount = createdcount + 1
Zerotorescue@0 116 return {}
Zerotorescue@0 117 end
Zerotorescue@0 118 end
Zerotorescue@0 119 function copy(t)
Zerotorescue@0 120 local c = new()
Zerotorescue@0 121 for k, v in pairs(t) do
Zerotorescue@0 122 c[k] = v
Zerotorescue@0 123 end
Zerotorescue@0 124 return c
Zerotorescue@0 125 end
Zerotorescue@0 126 function del(t)
Zerotorescue@0 127 --delcount = delcount + 1
Zerotorescue@0 128 for k in pairs(t) do
Zerotorescue@0 129 t[k] = nil
Zerotorescue@0 130 end
Zerotorescue@0 131 pool[t] = true
Zerotorescue@0 132 end
Zerotorescue@0 133 -- function cached()
Zerotorescue@0 134 -- local n = 0
Zerotorescue@0 135 -- for k in pairs(pool) do
Zerotorescue@0 136 -- n = n + 1
Zerotorescue@0 137 -- end
Zerotorescue@0 138 -- return n
Zerotorescue@0 139 -- end
Zerotorescue@0 140 end
Zerotorescue@0 141
Zerotorescue@0 142 -- picks the first non-nil value and returns it
Zerotorescue@0 143 local function pickfirstset(...)
Zerotorescue@0 144 for i=1,select("#",...) do
Zerotorescue@0 145 if select(i,...)~=nil then
Zerotorescue@0 146 return select(i,...)
Zerotorescue@0 147 end
Zerotorescue@0 148 end
Zerotorescue@0 149 end
Zerotorescue@0 150
Zerotorescue@0 151 --gets an option from a given group, checking plugins
Zerotorescue@0 152 local function GetSubOption(group, key)
Zerotorescue@0 153 if group.plugins then
Zerotorescue@0 154 for plugin, t in pairs(group.plugins) do
Zerotorescue@0 155 if t[key] then
Zerotorescue@0 156 return t[key]
Zerotorescue@0 157 end
Zerotorescue@0 158 end
Zerotorescue@0 159 end
Zerotorescue@0 160
Zerotorescue@0 161 return group.args[key]
Zerotorescue@0 162 end
Zerotorescue@0 163
Zerotorescue@0 164 --Option member type definitions, used to decide how to access it
Zerotorescue@0 165
Zerotorescue@0 166 --Is the member Inherited from parent options
Zerotorescue@0 167 local isInherited = {
Zerotorescue@0 168 set = true,
Zerotorescue@0 169 get = true,
Zerotorescue@0 170 func = true,
Zerotorescue@0 171 confirm = true,
Zerotorescue@0 172 validate = true,
Zerotorescue@0 173 disabled = true,
Zerotorescue@0 174 hidden = true
Zerotorescue@0 175 }
Zerotorescue@0 176
Zerotorescue@0 177 --Does a string type mean a literal value, instead of the default of a method of the handler
Zerotorescue@0 178 local stringIsLiteral = {
Zerotorescue@0 179 name = true,
Zerotorescue@0 180 desc = true,
Zerotorescue@0 181 icon = true,
Zerotorescue@0 182 usage = true,
Zerotorescue@0 183 width = true,
Zerotorescue@0 184 image = true,
Zerotorescue@0 185 fontSize = true,
Zerotorescue@0 186 }
Zerotorescue@0 187
Zerotorescue@0 188 --Is Never a function or method
Zerotorescue@0 189 local allIsLiteral = {
Zerotorescue@0 190 type = true,
Zerotorescue@0 191 descStyle = true,
Zerotorescue@0 192 imageWidth = true,
Zerotorescue@0 193 imageHeight = true,
Zerotorescue@0 194 }
Zerotorescue@0 195
Zerotorescue@0 196 --gets the value for a member that could be a function
Zerotorescue@0 197 --function refs are called with an info arg
Zerotorescue@0 198 --every other type is returned
Zerotorescue@0 199 local function GetOptionsMemberValue(membername, option, options, path, appName, ...)
Zerotorescue@0 200 --get definition for the member
Zerotorescue@0 201 local inherits = isInherited[membername]
Zerotorescue@0 202
Zerotorescue@0 203
Zerotorescue@0 204 --get the member of the option, traversing the tree if it can be inherited
Zerotorescue@0 205 local member
Zerotorescue@0 206
Zerotorescue@0 207 if inherits then
Zerotorescue@0 208 local group = options
Zerotorescue@0 209 if group[membername] ~= nil then
Zerotorescue@0 210 member = group[membername]
Zerotorescue@0 211 end
Zerotorescue@0 212 for i = 1, #path do
Zerotorescue@0 213 group = GetSubOption(group, path[i])
Zerotorescue@0 214 if group[membername] ~= nil then
Zerotorescue@0 215 member = group[membername]
Zerotorescue@0 216 end
Zerotorescue@0 217 end
Zerotorescue@0 218 else
Zerotorescue@0 219 member = option[membername]
Zerotorescue@0 220 end
Zerotorescue@0 221
Zerotorescue@0 222 --check if we need to call a functon, or if we have a literal value
Zerotorescue@0 223 if ( not allIsLiteral[membername] ) and ( type(member) == "function" or ((not stringIsLiteral[membername]) and type(member) == "string") ) then
Zerotorescue@0 224 --We have a function to call
Zerotorescue@0 225 local info = new()
Zerotorescue@0 226 --traverse the options table, picking up the handler and filling the info with the path
Zerotorescue@0 227 local handler
Zerotorescue@0 228 local group = options
Zerotorescue@0 229 handler = group.handler or handler
Zerotorescue@0 230
Zerotorescue@0 231 for i = 1, #path do
Zerotorescue@0 232 group = GetSubOption(group, path[i])
Zerotorescue@0 233 info[i] = path[i]
Zerotorescue@0 234 handler = group.handler or handler
Zerotorescue@0 235 end
Zerotorescue@0 236
Zerotorescue@0 237 info.options = options
Zerotorescue@0 238 info.appName = appName
Zerotorescue@0 239 info[0] = appName
Zerotorescue@0 240 info.arg = option.arg
Zerotorescue@0 241 info.handler = handler
Zerotorescue@0 242 info.option = option
Zerotorescue@0 243 info.type = option.type
Zerotorescue@0 244 info.uiType = "dialog"
Zerotorescue@0 245 info.uiName = MAJOR
Zerotorescue@0 246
Zerotorescue@0 247 local a, b, c ,d
Zerotorescue@0 248 --using 4 returns for the get of a color type, increase if a type needs more
Zerotorescue@0 249 if type(member) == "function" then
Zerotorescue@0 250 --Call the function
Zerotorescue@0 251 a,b,c,d = member(info, ...)
Zerotorescue@0 252 else
Zerotorescue@0 253 --Call the method
Zerotorescue@0 254 if handler and handler[member] then
Zerotorescue@0 255 a,b,c,d = handler[member](handler, info, ...)
Zerotorescue@0 256 else
Zerotorescue@0 257 error(format("Method %s doesn't exist in handler for type %s", member, membername))
Zerotorescue@0 258 end
Zerotorescue@0 259 end
Zerotorescue@0 260 del(info)
Zerotorescue@0 261 return a,b,c,d
Zerotorescue@0 262 else
Zerotorescue@0 263 --The value isnt a function to call, return it
Zerotorescue@0 264 return member
Zerotorescue@0 265 end
Zerotorescue@0 266 end
Zerotorescue@0 267
Zerotorescue@0 268 --[[calls an options function that could be inherited, method name or function ref
Zerotorescue@0 269 local function CallOptionsFunction(funcname ,option, options, path, appName, ...)
Zerotorescue@0 270 local info = new()
Zerotorescue@0 271
Zerotorescue@0 272 local func
Zerotorescue@0 273 local group = options
Zerotorescue@0 274 local handler
Zerotorescue@0 275
Zerotorescue@0 276 --build the info table containing the path
Zerotorescue@0 277 -- pick up functions while traversing the tree
Zerotorescue@0 278 if group[funcname] ~= nil then
Zerotorescue@0 279 func = group[funcname]
Zerotorescue@0 280 end
Zerotorescue@0 281 handler = group.handler or handler
Zerotorescue@0 282
Zerotorescue@0 283 for i, v in ipairs(path) do
Zerotorescue@0 284 group = GetSubOption(group, v)
Zerotorescue@0 285 info[i] = v
Zerotorescue@0 286 if group[funcname] ~= nil then
Zerotorescue@0 287 func = group[funcname]
Zerotorescue@0 288 end
Zerotorescue@0 289 handler = group.handler or handler
Zerotorescue@0 290 end
Zerotorescue@0 291
Zerotorescue@0 292 info.options = options
Zerotorescue@0 293 info[0] = appName
Zerotorescue@0 294 info.arg = option.arg
Zerotorescue@0 295
Zerotorescue@0 296 local a, b, c ,d
Zerotorescue@0 297 if type(func) == "string" then
Zerotorescue@0 298 if handler and handler[func] then
Zerotorescue@0 299 a,b,c,d = handler[func](handler, info, ...)
Zerotorescue@0 300 else
Zerotorescue@0 301 error(string.format("Method %s doesn't exist in handler for type func", func))
Zerotorescue@0 302 end
Zerotorescue@0 303 elseif type(func) == "function" then
Zerotorescue@0 304 a,b,c,d = func(info, ...)
Zerotorescue@0 305 end
Zerotorescue@0 306 del(info)
Zerotorescue@0 307 return a,b,c,d
Zerotorescue@0 308 end
Zerotorescue@0 309 --]]
Zerotorescue@0 310
Zerotorescue@0 311 --tables to hold orders and names for options being sorted, will be created with new()
Zerotorescue@0 312 --prevents needing to call functions repeatedly while sorting
Zerotorescue@0 313 local tempOrders
Zerotorescue@0 314 local tempNames
Zerotorescue@0 315
Zerotorescue@0 316 local function compareOptions(a,b)
Zerotorescue@0 317 if not a then
Zerotorescue@0 318 return true
Zerotorescue@0 319 end
Zerotorescue@0 320 if not b then
Zerotorescue@0 321 return false
Zerotorescue@0 322 end
Zerotorescue@0 323 local OrderA, OrderB = tempOrders[a] or 100, tempOrders[b] or 100
Zerotorescue@0 324 if OrderA == OrderB then
Zerotorescue@0 325 local NameA = (type(tempNames[a] == "string") and tempNames[a]) or ""
Zerotorescue@0 326 local NameB = (type(tempNames[b] == "string") and tempNames[b]) or ""
Zerotorescue@0 327 return NameA:upper() < NameB:upper()
Zerotorescue@0 328 end
Zerotorescue@0 329 if OrderA < 0 then
Zerotorescue@0 330 if OrderB > 0 then
Zerotorescue@0 331 return false
Zerotorescue@0 332 end
Zerotorescue@0 333 else
Zerotorescue@0 334 if OrderB < 0 then
Zerotorescue@0 335 return true
Zerotorescue@0 336 end
Zerotorescue@0 337 end
Zerotorescue@0 338 return OrderA < OrderB
Zerotorescue@0 339 end
Zerotorescue@0 340
Zerotorescue@0 341
Zerotorescue@0 342
Zerotorescue@0 343 --builds 2 tables out of an options group
Zerotorescue@0 344 -- keySort, sorted keys
Zerotorescue@0 345 -- opts, combined options from .plugins and args
Zerotorescue@0 346 local function BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
Zerotorescue@0 347 tempOrders = new()
Zerotorescue@0 348 tempNames = new()
Zerotorescue@0 349
Zerotorescue@0 350 if group.plugins then
Zerotorescue@0 351 for plugin, t in pairs(group.plugins) do
Zerotorescue@0 352 for k, v in pairs(t) do
Zerotorescue@0 353 if not opts[k] then
Zerotorescue@0 354 tinsert(keySort, k)
Zerotorescue@0 355 opts[k] = v
Zerotorescue@0 356
Zerotorescue@0 357 path[#path+1] = k
Zerotorescue@0 358 tempOrders[k] = GetOptionsMemberValue("order", v, options, path, appName)
Zerotorescue@0 359 tempNames[k] = GetOptionsMemberValue("name", v, options, path, appName)
Zerotorescue@0 360 path[#path] = nil
Zerotorescue@0 361 end
Zerotorescue@0 362 end
Zerotorescue@0 363 end
Zerotorescue@0 364 end
Zerotorescue@0 365
Zerotorescue@0 366 for k, v in pairs(group.args) do
Zerotorescue@0 367 if not opts[k] then
Zerotorescue@0 368 tinsert(keySort, k)
Zerotorescue@0 369 opts[k] = v
Zerotorescue@0 370
Zerotorescue@0 371 path[#path+1] = k
Zerotorescue@0 372 tempOrders[k] = GetOptionsMemberValue("order", v, options, path, appName)
Zerotorescue@0 373 tempNames[k] = GetOptionsMemberValue("name", v, options, path, appName)
Zerotorescue@0 374 path[#path] = nil
Zerotorescue@0 375 end
Zerotorescue@0 376 end
Zerotorescue@0 377
Zerotorescue@0 378 tsort(keySort, compareOptions)
Zerotorescue@0 379
Zerotorescue@0 380 del(tempOrders)
Zerotorescue@0 381 del(tempNames)
Zerotorescue@0 382 end
Zerotorescue@0 383
Zerotorescue@0 384 local function DelTree(tree)
Zerotorescue@0 385 if tree.children then
Zerotorescue@0 386 local childs = tree.children
Zerotorescue@0 387 for i = 1, #childs do
Zerotorescue@0 388 DelTree(childs[i])
Zerotorescue@0 389 del(childs[i])
Zerotorescue@0 390 end
Zerotorescue@0 391 del(childs)
Zerotorescue@0 392 end
Zerotorescue@0 393 end
Zerotorescue@0 394
Zerotorescue@0 395 local function CleanUserData(widget, event)
Zerotorescue@0 396
Zerotorescue@0 397 local user = widget:GetUserDataTable()
Zerotorescue@0 398
Zerotorescue@0 399 if user.path then
Zerotorescue@0 400 del(user.path)
Zerotorescue@0 401 end
Zerotorescue@0 402
Zerotorescue@0 403 if widget.type == "TreeGroup" then
Zerotorescue@0 404 local tree = user.tree
Zerotorescue@0 405 widget:SetTree(nil)
Zerotorescue@0 406 if tree then
Zerotorescue@0 407 for i = 1, #tree do
Zerotorescue@0 408 DelTree(tree[i])
Zerotorescue@0 409 del(tree[i])
Zerotorescue@0 410 end
Zerotorescue@0 411 del(tree)
Zerotorescue@0 412 end
Zerotorescue@0 413 end
Zerotorescue@0 414
Zerotorescue@0 415 if widget.type == "TabGroup" then
Zerotorescue@0 416 widget:SetTabs(nil)
Zerotorescue@0 417 if user.tablist then
Zerotorescue@0 418 del(user.tablist)
Zerotorescue@0 419 end
Zerotorescue@0 420 end
Zerotorescue@0 421
Zerotorescue@0 422 if widget.type == "DropdownGroup" then
Zerotorescue@0 423 widget:SetGroupList(nil)
Zerotorescue@0 424 if user.grouplist then
Zerotorescue@0 425 del(user.grouplist)
Zerotorescue@0 426 end
Zerotorescue@0 427 end
Zerotorescue@0 428 end
Zerotorescue@0 429
Zerotorescue@0 430 -- - Gets a status table for the given appname and options path.
Zerotorescue@0 431 -- @param appName The application name as given to `:RegisterOptionsTable()`
Zerotorescue@0 432 -- @param path The path to the options (a table with all group keys)
Zerotorescue@0 433 -- @return
Zerotorescue@0 434 function AceConfigDialog:GetStatusTable(appName, path)
Zerotorescue@0 435 local status = self.Status
Zerotorescue@0 436
Zerotorescue@0 437 if not status[appName] then
Zerotorescue@0 438 status[appName] = {}
Zerotorescue@0 439 status[appName].status = {}
Zerotorescue@0 440 status[appName].children = {}
Zerotorescue@0 441 end
Zerotorescue@0 442
Zerotorescue@0 443 status = status[appName]
Zerotorescue@0 444
Zerotorescue@0 445 if path then
Zerotorescue@0 446 for i = 1, #path do
Zerotorescue@0 447 local v = path[i]
Zerotorescue@0 448 if not status.children[v] then
Zerotorescue@0 449 status.children[v] = {}
Zerotorescue@0 450 status.children[v].status = {}
Zerotorescue@0 451 status.children[v].children = {}
Zerotorescue@0 452 end
Zerotorescue@0 453 status = status.children[v]
Zerotorescue@0 454 end
Zerotorescue@0 455 end
Zerotorescue@0 456
Zerotorescue@0 457 return status.status
Zerotorescue@0 458 end
Zerotorescue@0 459
Zerotorescue@0 460 --- Selects the specified path in the options window.
Zerotorescue@0 461 -- The path specified has to match the keys of the groups in the table.
Zerotorescue@0 462 -- @param appName The application name as given to `:RegisterOptionsTable()`
Zerotorescue@0 463 -- @param ... The path to the key that should be selected
Zerotorescue@0 464 function AceConfigDialog:SelectGroup(appName, ...)
Zerotorescue@0 465 local path = new()
Zerotorescue@0 466
Zerotorescue@0 467
Zerotorescue@0 468 local app = reg:GetOptionsTable(appName)
Zerotorescue@0 469 if not app then
Zerotorescue@0 470 error(("%s isn't registed with AceConfigRegistry, unable to open config"):format(appName), 2)
Zerotorescue@0 471 end
Zerotorescue@0 472 local options = app("dialog", MAJOR)
Zerotorescue@0 473 local group = options
Zerotorescue@0 474 local status = self:GetStatusTable(appName, path)
Zerotorescue@0 475 if not status.groups then
Zerotorescue@0 476 status.groups = {}
Zerotorescue@0 477 end
Zerotorescue@0 478 status = status.groups
Zerotorescue@0 479 local treevalue
Zerotorescue@0 480 local treestatus
Zerotorescue@0 481
Zerotorescue@0 482 for n = 1, select("#",...) do
Zerotorescue@0 483 local key = select(n, ...)
Zerotorescue@0 484
Zerotorescue@0 485 if group.childGroups == "tab" or group.childGroups == "select" then
Zerotorescue@0 486 --if this is a tab or select group, select the group
Zerotorescue@0 487 status.selected = key
Zerotorescue@0 488 --children of this group are no longer extra levels of a tree
Zerotorescue@0 489 treevalue = nil
Zerotorescue@0 490 else
Zerotorescue@0 491 --tree group by default
Zerotorescue@0 492 if treevalue then
Zerotorescue@0 493 --this is an extra level of a tree group, build a uniquevalue for it
Zerotorescue@0 494 treevalue = treevalue.."\001"..key
Zerotorescue@0 495 else
Zerotorescue@0 496 --this is the top level of a tree group, the uniquevalue is the same as the key
Zerotorescue@0 497 treevalue = key
Zerotorescue@0 498 if not status.groups then
Zerotorescue@0 499 status.groups = {}
Zerotorescue@0 500 end
Zerotorescue@0 501 --save this trees status table for any extra levels or groups
Zerotorescue@0 502 treestatus = status
Zerotorescue@0 503 end
Zerotorescue@0 504 --make sure that the tree entry is open, and select it.
Zerotorescue@0 505 --the selected group will be overwritten if a child is the final target but still needs to be open
Zerotorescue@0 506 treestatus.selected = treevalue
Zerotorescue@0 507 treestatus.groups[treevalue] = true
Zerotorescue@0 508
Zerotorescue@0 509 end
Zerotorescue@0 510
Zerotorescue@0 511 --move to the next group in the path
Zerotorescue@0 512 group = GetSubOption(group, key)
Zerotorescue@0 513 if not group then
Zerotorescue@0 514 break
Zerotorescue@0 515 end
Zerotorescue@0 516 tinsert(path, key)
Zerotorescue@0 517 status = self:GetStatusTable(appName, path)
Zerotorescue@0 518 if not status.groups then
Zerotorescue@0 519 status.groups = {}
Zerotorescue@0 520 end
Zerotorescue@0 521 status = status.groups
Zerotorescue@0 522 end
Zerotorescue@0 523
Zerotorescue@0 524 del(path)
Zerotorescue@0 525 reg:NotifyChange(appName)
Zerotorescue@0 526 end
Zerotorescue@0 527
Zerotorescue@0 528 local function OptionOnMouseOver(widget, event)
Zerotorescue@0 529 --show a tooltip/set the status bar to the desc text
Zerotorescue@0 530 local user = widget:GetUserDataTable()
Zerotorescue@0 531 local opt = user.option
Zerotorescue@0 532 local options = user.options
Zerotorescue@0 533 local path = user.path
Zerotorescue@0 534 local appName = user.appName
Zerotorescue@0 535
Zerotorescue@0 536 GameTooltip:SetOwner(widget.frame, "ANCHOR_TOPRIGHT")
Zerotorescue@0 537 local name = GetOptionsMemberValue("name", opt, options, path, appName)
Zerotorescue@0 538 local desc = GetOptionsMemberValue("desc", opt, options, path, appName)
Zerotorescue@0 539 local usage = GetOptionsMemberValue("usage", opt, options, path, appName)
Zerotorescue@0 540 local descStyle = opt.descStyle
Zerotorescue@0 541
Zerotorescue@0 542 if descStyle and descStyle ~= "tooltip" then return end
Zerotorescue@0 543
Zerotorescue@0 544 GameTooltip:SetText(name, 1, .82, 0, 1)
Zerotorescue@0 545
Zerotorescue@0 546 if opt.type == "multiselect" then
Zerotorescue@0 547 GameTooltip:AddLine(user.text,0.5, 0.5, 0.8, 1)
Zerotorescue@0 548 end
Zerotorescue@0 549 if type(desc) == "string" then
Zerotorescue@0 550 GameTooltip:AddLine(desc, 1, 1, 1, 1)
Zerotorescue@0 551 end
Zerotorescue@0 552 if type(usage) == "string" then
Zerotorescue@0 553 GameTooltip:AddLine("Usage: "..usage, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1)
Zerotorescue@0 554 end
Zerotorescue@0 555
Zerotorescue@0 556 GameTooltip:Show()
Zerotorescue@0 557 end
Zerotorescue@0 558
Zerotorescue@0 559 local function OptionOnMouseLeave(widget, event)
Zerotorescue@0 560 GameTooltip:Hide()
Zerotorescue@0 561 end
Zerotorescue@0 562
Zerotorescue@0 563 local function GetFuncName(option)
Zerotorescue@0 564 local type = option.type
Zerotorescue@0 565 if type == "execute" then
Zerotorescue@0 566 return "func"
Zerotorescue@0 567 else
Zerotorescue@0 568 return "set"
Zerotorescue@0 569 end
Zerotorescue@0 570 end
Zerotorescue@0 571 local function confirmPopup(appName, rootframe, basepath, info, message, func, ...)
Zerotorescue@0 572 if not StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"] then
Zerotorescue@0 573 StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"] = {}
Zerotorescue@0 574 end
Zerotorescue@0 575 local t = StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"]
Zerotorescue@0 576 for k in pairs(t) do
Zerotorescue@0 577 t[k] = nil
Zerotorescue@0 578 end
Zerotorescue@0 579 t.text = message
Zerotorescue@0 580 t.button1 = ACCEPT
Zerotorescue@0 581 t.button2 = CANCEL
Zerotorescue@0 582 local dialog, oldstrata
Zerotorescue@0 583 t.OnAccept = function()
Zerotorescue@0 584 safecall(func, unpack(t))
Zerotorescue@0 585 if dialog and oldstrata then
Zerotorescue@0 586 dialog:SetFrameStrata(oldstrata)
Zerotorescue@0 587 end
Zerotorescue@0 588 AceConfigDialog:Open(appName, rootframe, unpack(basepath or emptyTbl))
Zerotorescue@0 589 del(info)
Zerotorescue@0 590 end
Zerotorescue@0 591 t.OnCancel = function()
Zerotorescue@0 592 if dialog and oldstrata then
Zerotorescue@0 593 dialog:SetFrameStrata(oldstrata)
Zerotorescue@0 594 end
Zerotorescue@0 595 AceConfigDialog:Open(appName, rootframe, unpack(basepath or emptyTbl))
Zerotorescue@0 596 del(info)
Zerotorescue@0 597 end
Zerotorescue@0 598 for i = 1, select("#", ...) do
Zerotorescue@0 599 t[i] = select(i, ...) or false
Zerotorescue@0 600 end
Zerotorescue@0 601 t.timeout = 0
Zerotorescue@0 602 t.whileDead = 1
Zerotorescue@0 603 t.hideOnEscape = 1
Zerotorescue@0 604
Zerotorescue@0 605 dialog = StaticPopup_Show("ACECONFIGDIALOG30_CONFIRM_DIALOG")
Zerotorescue@0 606 if dialog then
Zerotorescue@0 607 oldstrata = dialog:GetFrameStrata()
Zerotorescue@0 608 dialog:SetFrameStrata("TOOLTIP")
Zerotorescue@0 609 end
Zerotorescue@0 610 end
Zerotorescue@0 611
Zerotorescue@0 612 local function ActivateControl(widget, event, ...)
Zerotorescue@0 613 --This function will call the set / execute handler for the widget
Zerotorescue@0 614 --widget:GetUserDataTable() contains the needed info
Zerotorescue@0 615 local user = widget:GetUserDataTable()
Zerotorescue@0 616 local option = user.option
Zerotorescue@0 617 local options = user.options
Zerotorescue@0 618 local path = user.path
Zerotorescue@0 619 local info = new()
Zerotorescue@0 620
Zerotorescue@0 621 local func
Zerotorescue@0 622 local group = options
Zerotorescue@0 623 local funcname = GetFuncName(option)
Zerotorescue@0 624 local handler
Zerotorescue@0 625 local confirm
Zerotorescue@0 626 local validate
Zerotorescue@0 627 --build the info table containing the path
Zerotorescue@0 628 -- pick up functions while traversing the tree
Zerotorescue@0 629 if group[funcname] ~= nil then
Zerotorescue@0 630 func = group[funcname]
Zerotorescue@0 631 end
Zerotorescue@0 632 handler = group.handler or handler
Zerotorescue@0 633 confirm = group.confirm
Zerotorescue@0 634 validate = group.validate
Zerotorescue@0 635 for i = 1, #path do
Zerotorescue@0 636 local v = path[i]
Zerotorescue@0 637 group = GetSubOption(group, v)
Zerotorescue@0 638 info[i] = v
Zerotorescue@0 639 if group[funcname] ~= nil then
Zerotorescue@0 640 func = group[funcname]
Zerotorescue@0 641 end
Zerotorescue@0 642 handler = group.handler or handler
Zerotorescue@0 643 if group.confirm ~= nil then
Zerotorescue@0 644 confirm = group.confirm
Zerotorescue@0 645 end
Zerotorescue@0 646 if group.validate ~= nil then
Zerotorescue@0 647 validate = group.validate
Zerotorescue@0 648 end
Zerotorescue@0 649 end
Zerotorescue@0 650
Zerotorescue@0 651 info.options = options
Zerotorescue@0 652 info.appName = user.appName
Zerotorescue@0 653 info.arg = option.arg
Zerotorescue@0 654 info.handler = handler
Zerotorescue@0 655 info.option = option
Zerotorescue@0 656 info.type = option.type
Zerotorescue@0 657 info.uiType = "dialog"
Zerotorescue@0 658 info.uiName = MAJOR
Zerotorescue@0 659
Zerotorescue@0 660 local name
Zerotorescue@0 661 if type(option.name) == "function" then
Zerotorescue@0 662 name = option.name(info)
Zerotorescue@0 663 elseif type(option.name) == "string" then
Zerotorescue@0 664 name = option.name
Zerotorescue@0 665 else
Zerotorescue@0 666 name = ""
Zerotorescue@0 667 end
Zerotorescue@0 668 local usage = option.usage
Zerotorescue@0 669 local pattern = option.pattern
Zerotorescue@0 670
Zerotorescue@0 671 local validated = true
Zerotorescue@0 672
Zerotorescue@0 673 if option.type == "input" then
Zerotorescue@0 674 if type(pattern)=="string" then
Zerotorescue@0 675 if not strmatch(..., pattern) then
Zerotorescue@0 676 validated = false
Zerotorescue@0 677 end
Zerotorescue@0 678 end
Zerotorescue@0 679 end
Zerotorescue@0 680
Zerotorescue@0 681 local success
Zerotorescue@0 682 if validated and option.type ~= "execute" then
Zerotorescue@0 683 if type(validate) == "string" then
Zerotorescue@0 684 if handler and handler[validate] then
Zerotorescue@0 685 success, validated = safecall(handler[validate], handler, info, ...)
Zerotorescue@0 686 if not success then validated = false end
Zerotorescue@0 687 else
Zerotorescue@0 688 error(format("Method %s doesn't exist in handler for type execute", validate))
Zerotorescue@0 689 end
Zerotorescue@0 690 elseif type(validate) == "function" then
Zerotorescue@0 691 success, validated = safecall(validate, info, ...)
Zerotorescue@0 692 if not success then validated = false end
Zerotorescue@0 693 end
Zerotorescue@0 694 end
Zerotorescue@0 695
Zerotorescue@0 696 local rootframe = user.rootframe
Zerotorescue@0 697 if type(validated) == "string" then
Zerotorescue@0 698 --validate function returned a message to display
Zerotorescue@0 699 if rootframe.SetStatusText then
Zerotorescue@0 700 rootframe:SetStatusText(validated)
Zerotorescue@0 701 else
Zerotorescue@0 702 -- TODO: do something else.
Zerotorescue@0 703 end
Zerotorescue@0 704 PlaySound("igPlayerInviteDecline")
Zerotorescue@0 705 del(info)
Zerotorescue@0 706 return true
Zerotorescue@0 707 elseif not validated then
Zerotorescue@0 708 --validate returned false
Zerotorescue@0 709 if rootframe.SetStatusText then
Zerotorescue@0 710 if usage then
Zerotorescue@0 711 rootframe:SetStatusText(name..": "..usage)
Zerotorescue@0 712 else
Zerotorescue@0 713 if pattern then
Zerotorescue@0 714 rootframe:SetStatusText(name..": Expected "..pattern)
Zerotorescue@0 715 else
Zerotorescue@0 716 rootframe:SetStatusText(name..": Invalid Value")
Zerotorescue@0 717 end
Zerotorescue@0 718 end
Zerotorescue@0 719 else
Zerotorescue@0 720 -- TODO: do something else
Zerotorescue@0 721 end
Zerotorescue@0 722 PlaySound("igPlayerInviteDecline")
Zerotorescue@0 723 del(info)
Zerotorescue@0 724 return true
Zerotorescue@0 725 else
Zerotorescue@0 726
Zerotorescue@0 727 local confirmText = option.confirmText
Zerotorescue@0 728 --call confirm func/method
Zerotorescue@0 729 if type(confirm) == "string" then
Zerotorescue@0 730 if handler and handler[confirm] then
Zerotorescue@0 731 success, confirm = safecall(handler[confirm], handler, info, ...)
Zerotorescue@0 732 if success and type(confirm) == "string" then
Zerotorescue@0 733 confirmText = confirm
Zerotorescue@0 734 confirm = true
Zerotorescue@0 735 elseif not success then
Zerotorescue@0 736 confirm = false
Zerotorescue@0 737 end
Zerotorescue@0 738 else
Zerotorescue@0 739 error(format("Method %s doesn't exist in handler for type confirm", confirm))
Zerotorescue@0 740 end
Zerotorescue@0 741 elseif type(confirm) == "function" then
Zerotorescue@0 742 success, confirm = safecall(confirm, info, ...)
Zerotorescue@0 743 if success and type(confirm) == "string" then
Zerotorescue@0 744 confirmText = confirm
Zerotorescue@0 745 confirm = true
Zerotorescue@0 746 elseif not success then
Zerotorescue@0 747 confirm = false
Zerotorescue@0 748 end
Zerotorescue@0 749 end
Zerotorescue@0 750
Zerotorescue@0 751 --confirm if needed
Zerotorescue@0 752 if type(confirm) == "boolean" then
Zerotorescue@0 753 if confirm then
Zerotorescue@0 754 if not confirmText then
Zerotorescue@0 755 local name, desc = option.name, option.desc
Zerotorescue@0 756 if type(name) == "function" then
Zerotorescue@0 757 name = name(info)
Zerotorescue@0 758 end
Zerotorescue@0 759 if type(desc) == "function" then
Zerotorescue@0 760 desc = desc(info)
Zerotorescue@0 761 end
Zerotorescue@0 762 confirmText = name
Zerotorescue@0 763 if desc then
Zerotorescue@0 764 confirmText = confirmText.." - "..desc
Zerotorescue@0 765 end
Zerotorescue@0 766 end
Zerotorescue@0 767
Zerotorescue@0 768 local iscustom = user.rootframe:GetUserData("iscustom")
Zerotorescue@0 769 local rootframe
Zerotorescue@0 770
Zerotorescue@0 771 if iscustom then
Zerotorescue@0 772 rootframe = user.rootframe
Zerotorescue@0 773 end
Zerotorescue@0 774 local basepath = user.rootframe:GetUserData("basepath")
Zerotorescue@0 775 if type(func) == "string" then
Zerotorescue@0 776 if handler and handler[func] then
Zerotorescue@0 777 confirmPopup(user.appName, rootframe, basepath, info, confirmText, handler[func], handler, info, ...)
Zerotorescue@0 778 else
Zerotorescue@0 779 error(format("Method %s doesn't exist in handler for type func", func))
Zerotorescue@0 780 end
Zerotorescue@0 781 elseif type(func) == "function" then
Zerotorescue@0 782 confirmPopup(user.appName, rootframe, basepath, info, confirmText, func, info, ...)
Zerotorescue@0 783 end
Zerotorescue@0 784 --func will be called and info deleted when the confirm dialog is responded to
Zerotorescue@0 785 return
Zerotorescue@0 786 end
Zerotorescue@0 787 end
Zerotorescue@0 788
Zerotorescue@0 789 --call the function
Zerotorescue@0 790 if type(func) == "string" then
Zerotorescue@0 791 if handler and handler[func] then
Zerotorescue@0 792 safecall(handler[func],handler, info, ...)
Zerotorescue@0 793 else
Zerotorescue@0 794 error(format("Method %s doesn't exist in handler for type func", func))
Zerotorescue@0 795 end
Zerotorescue@0 796 elseif type(func) == "function" then
Zerotorescue@0 797 safecall(func,info, ...)
Zerotorescue@0 798 end
Zerotorescue@0 799
Zerotorescue@0 800
Zerotorescue@0 801
Zerotorescue@0 802 local iscustom = user.rootframe:GetUserData("iscustom")
Zerotorescue@0 803 local basepath = user.rootframe:GetUserData("basepath") or emptyTbl
Zerotorescue@0 804 --full refresh of the frame, some controls dont cause this on all events
Zerotorescue@0 805 if option.type == "color" then
Zerotorescue@0 806 if event == "OnValueConfirmed" then
Zerotorescue@0 807
Zerotorescue@0 808 if iscustom then
Zerotorescue@0 809 AceConfigDialog:Open(user.appName, user.rootframe, unpack(basepath))
Zerotorescue@0 810 else
Zerotorescue@0 811 AceConfigDialog:Open(user.appName, unpack(basepath))
Zerotorescue@0 812 end
Zerotorescue@0 813 end
Zerotorescue@0 814 elseif option.type == "range" then
Zerotorescue@0 815 if event == "OnMouseUp" then
Zerotorescue@0 816 if iscustom then
Zerotorescue@0 817 AceConfigDialog:Open(user.appName, user.rootframe, unpack(basepath))
Zerotorescue@0 818 else
Zerotorescue@0 819 AceConfigDialog:Open(user.appName, unpack(basepath))
Zerotorescue@0 820 end
Zerotorescue@0 821 end
Zerotorescue@0 822 --multiselects don't cause a refresh on 'OnValueChanged' only 'OnClosed'
Zerotorescue@0 823 elseif option.type == "multiselect" then
Zerotorescue@0 824 user.valuechanged = true
Zerotorescue@0 825 else
Zerotorescue@0 826 if iscustom then
Zerotorescue@0 827 AceConfigDialog:Open(user.appName, user.rootframe, unpack(basepath))
Zerotorescue@0 828 else
Zerotorescue@0 829 AceConfigDialog:Open(user.appName, unpack(basepath))
Zerotorescue@0 830 end
Zerotorescue@0 831 end
Zerotorescue@0 832
Zerotorescue@0 833 end
Zerotorescue@0 834 del(info)
Zerotorescue@0 835 end
Zerotorescue@0 836
Zerotorescue@0 837 local function ActivateSlider(widget, event, value)
Zerotorescue@0 838 local option = widget:GetUserData("option")
Zerotorescue@0 839 local min, max, step = option.min or (not option.softMin and 0 or nil), option.max or (not option.softMax and 100 or nil), option.step
Zerotorescue@0 840 if min then
Zerotorescue@0 841 if step then
Zerotorescue@0 842 value = math_floor((value - min) / step + 0.5) * step + min
Zerotorescue@0 843 end
Zerotorescue@0 844 value = math_max(value, min)
Zerotorescue@0 845 end
Zerotorescue@0 846 if max then
Zerotorescue@0 847 value = math_min(value, max)
Zerotorescue@0 848 end
Zerotorescue@0 849 ActivateControl(widget,event,value)
Zerotorescue@0 850 end
Zerotorescue@0 851
Zerotorescue@0 852 --called from a checkbox that is part of an internally created multiselect group
Zerotorescue@0 853 --this type is safe to refresh on activation of one control
Zerotorescue@0 854 local function ActivateMultiControl(widget, event, ...)
Zerotorescue@0 855 ActivateControl(widget, event, widget:GetUserData("value"), ...)
Zerotorescue@0 856 local user = widget:GetUserDataTable()
Zerotorescue@0 857 local iscustom = user.rootframe:GetUserData("iscustom")
Zerotorescue@0 858 local basepath = user.rootframe:GetUserData("basepath") or emptyTbl
Zerotorescue@0 859 if iscustom then
Zerotorescue@0 860 AceConfigDialog:Open(user.appName, user.rootframe, unpack(basepath))
Zerotorescue@0 861 else
Zerotorescue@0 862 AceConfigDialog:Open(user.appName, unpack(basepath))
Zerotorescue@0 863 end
Zerotorescue@0 864 end
Zerotorescue@0 865
Zerotorescue@0 866 local function MultiControlOnClosed(widget, event, ...)
Zerotorescue@0 867 local user = widget:GetUserDataTable()
Zerotorescue@0 868 if user.valuechanged then
Zerotorescue@0 869 local iscustom = user.rootframe:GetUserData("iscustom")
Zerotorescue@0 870 local basepath = user.rootframe:GetUserData("basepath") or emptyTbl
Zerotorescue@0 871 if iscustom then
Zerotorescue@0 872 AceConfigDialog:Open(user.appName, user.rootframe, unpack(basepath))
Zerotorescue@0 873 else
Zerotorescue@0 874 AceConfigDialog:Open(user.appName, unpack(basepath))
Zerotorescue@0 875 end
Zerotorescue@0 876 end
Zerotorescue@0 877 end
Zerotorescue@0 878
Zerotorescue@0 879 local function FrameOnClose(widget, event)
Zerotorescue@0 880 local appName = widget:GetUserData("appName")
Zerotorescue@0 881 AceConfigDialog.OpenFrames[appName] = nil
Zerotorescue@0 882 gui:Release(widget)
Zerotorescue@0 883 end
Zerotorescue@0 884
Zerotorescue@0 885 local function CheckOptionHidden(option, options, path, appName)
Zerotorescue@0 886 --check for a specific boolean option
Zerotorescue@0 887 local hidden = pickfirstset(option.dialogHidden,option.guiHidden)
Zerotorescue@0 888 if hidden ~= nil then
Zerotorescue@0 889 return hidden
Zerotorescue@0 890 end
Zerotorescue@0 891
Zerotorescue@0 892 return GetOptionsMemberValue("hidden", option, options, path, appName)
Zerotorescue@0 893 end
Zerotorescue@0 894
Zerotorescue@0 895 local function CheckOptionDisabled(option, options, path, appName)
Zerotorescue@0 896 --check for a specific boolean option
Zerotorescue@0 897 local disabled = pickfirstset(option.dialogDisabled,option.guiDisabled)
Zerotorescue@0 898 if disabled ~= nil then
Zerotorescue@0 899 return disabled
Zerotorescue@0 900 end
Zerotorescue@0 901
Zerotorescue@0 902 return GetOptionsMemberValue("disabled", option, options, path, appName)
Zerotorescue@0 903 end
Zerotorescue@0 904 --[[
Zerotorescue@0 905 local function BuildTabs(group, options, path, appName)
Zerotorescue@0 906 local tabs = new()
Zerotorescue@0 907 local text = new()
Zerotorescue@0 908 local keySort = new()
Zerotorescue@0 909 local opts = new()
Zerotorescue@0 910
Zerotorescue@0 911 BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
Zerotorescue@0 912
Zerotorescue@0 913 for i = 1, #keySort do
Zerotorescue@0 914 local k = keySort[i]
Zerotorescue@0 915 local v = opts[k]
Zerotorescue@0 916 if v.type == "group" then
Zerotorescue@0 917 path[#path+1] = k
Zerotorescue@0 918 local inline = pickfirstset(v.dialogInline,v.guiInline,v.inline, false)
Zerotorescue@0 919 local hidden = CheckOptionHidden(v, options, path, appName)
Zerotorescue@0 920 if not inline and not hidden then
Zerotorescue@0 921 tinsert(tabs, k)
Zerotorescue@0 922 text[k] = GetOptionsMemberValue("name", v, options, path, appName)
Zerotorescue@0 923 end
Zerotorescue@0 924 path[#path] = nil
Zerotorescue@0 925 end
Zerotorescue@0 926 end
Zerotorescue@0 927
Zerotorescue@0 928 del(keySort)
Zerotorescue@0 929 del(opts)
Zerotorescue@0 930
Zerotorescue@0 931 return tabs, text
Zerotorescue@0 932 end
Zerotorescue@0 933 ]]
Zerotorescue@0 934 local function BuildSelect(group, options, path, appName)
Zerotorescue@0 935 local groups = new()
Zerotorescue@0 936 local keySort = new()
Zerotorescue@0 937 local opts = new()
Zerotorescue@0 938
Zerotorescue@0 939 BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
Zerotorescue@0 940
Zerotorescue@0 941 for i = 1, #keySort do
Zerotorescue@0 942 local k = keySort[i]
Zerotorescue@0 943 local v = opts[k]
Zerotorescue@0 944 if v.type == "group" then
Zerotorescue@0 945 path[#path+1] = k
Zerotorescue@0 946 local inline = pickfirstset(v.dialogInline,v.guiInline,v.inline, false)
Zerotorescue@0 947 local hidden = CheckOptionHidden(v, options, path, appName)
Zerotorescue@0 948 if not inline and not hidden then
Zerotorescue@0 949 groups[k] = GetOptionsMemberValue("name", v, options, path, appName)
Zerotorescue@0 950 end
Zerotorescue@0 951 path[#path] = nil
Zerotorescue@0 952 end
Zerotorescue@0 953 end
Zerotorescue@0 954
Zerotorescue@0 955 del(keySort)
Zerotorescue@0 956 del(opts)
Zerotorescue@0 957
Zerotorescue@0 958 return groups
Zerotorescue@0 959 end
Zerotorescue@0 960
Zerotorescue@0 961 local function BuildSubGroups(group, tree, options, path, appName)
Zerotorescue@0 962 local keySort = new()
Zerotorescue@0 963 local opts = new()
Zerotorescue@0 964
Zerotorescue@0 965 BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
Zerotorescue@0 966
Zerotorescue@0 967 for i = 1, #keySort do
Zerotorescue@0 968 local k = keySort[i]
Zerotorescue@0 969 local v = opts[k]
Zerotorescue@0 970 if v.type == "group" then
Zerotorescue@0 971 path[#path+1] = k
Zerotorescue@0 972 local inline = pickfirstset(v.dialogInline,v.guiInline,v.inline, false)
Zerotorescue@0 973 local hidden = CheckOptionHidden(v, options, path, appName)
Zerotorescue@0 974 if not inline and not hidden then
Zerotorescue@0 975 local entry = new()
Zerotorescue@0 976 entry.value = k
Zerotorescue@0 977 entry.text = GetOptionsMemberValue("name", v, options, path, appName)
Zerotorescue@0 978 entry.icon = GetOptionsMemberValue("icon", v, options, path, appName)
Zerotorescue@0 979 entry.iconCoords = GetOptionsMemberValue("iconCoords", v, options, path, appName)
Zerotorescue@0 980 entry.disabled = CheckOptionDisabled(v, options, path, appName)
Zerotorescue@0 981 if not tree.children then tree.children = new() end
Zerotorescue@0 982 tinsert(tree.children,entry)
Zerotorescue@0 983 if (v.childGroups or "tree") == "tree" then
Zerotorescue@0 984 BuildSubGroups(v,entry, options, path, appName)
Zerotorescue@0 985 end
Zerotorescue@0 986 end
Zerotorescue@0 987 path[#path] = nil
Zerotorescue@0 988 end
Zerotorescue@0 989 end
Zerotorescue@0 990
Zerotorescue@0 991 del(keySort)
Zerotorescue@0 992 del(opts)
Zerotorescue@0 993 end
Zerotorescue@0 994
Zerotorescue@0 995 local function BuildGroups(group, options, path, appName, recurse)
Zerotorescue@0 996 local tree = new()
Zerotorescue@0 997 local keySort = new()
Zerotorescue@0 998 local opts = new()
Zerotorescue@0 999
Zerotorescue@0 1000 BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
Zerotorescue@0 1001
Zerotorescue@0 1002 for i = 1, #keySort do
Zerotorescue@0 1003 local k = keySort[i]
Zerotorescue@0 1004 local v = opts[k]
Zerotorescue@0 1005 if v.type == "group" then
Zerotorescue@0 1006 path[#path+1] = k
Zerotorescue@0 1007 local inline = pickfirstset(v.dialogInline,v.guiInline,v.inline, false)
Zerotorescue@0 1008 local hidden = CheckOptionHidden(v, options, path, appName)
Zerotorescue@0 1009 if not inline and not hidden then
Zerotorescue@0 1010 local entry = new()
Zerotorescue@0 1011 entry.value = k
Zerotorescue@0 1012 entry.text = GetOptionsMemberValue("name", v, options, path, appName)
Zerotorescue@0 1013 entry.icon = GetOptionsMemberValue("icon", v, options, path, appName)
Zerotorescue@0 1014 entry.disabled = CheckOptionDisabled(v, options, path, appName)
Zerotorescue@0 1015 tinsert(tree,entry)
Zerotorescue@0 1016 if recurse and (v.childGroups or "tree") == "tree" then
Zerotorescue@0 1017 BuildSubGroups(v,entry, options, path, appName)
Zerotorescue@0 1018 end
Zerotorescue@0 1019 end
Zerotorescue@0 1020 path[#path] = nil
Zerotorescue@0 1021 end
Zerotorescue@0 1022 end
Zerotorescue@0 1023 del(keySort)
Zerotorescue@0 1024 del(opts)
Zerotorescue@0 1025 return tree
Zerotorescue@0 1026 end
Zerotorescue@0 1027
Zerotorescue@0 1028 local function InjectInfo(control, options, option, path, rootframe, appName)
Zerotorescue@0 1029 local user = control:GetUserDataTable()
Zerotorescue@0 1030 for i = 1, #path do
Zerotorescue@0 1031 user[i] = path[i]
Zerotorescue@0 1032 end
Zerotorescue@0 1033 user.rootframe = rootframe
Zerotorescue@0 1034 user.option = option
Zerotorescue@0 1035 user.options = options
Zerotorescue@0 1036 user.path = copy(path)
Zerotorescue@0 1037 user.appName = appName
Zerotorescue@0 1038 control:SetCallback("OnRelease", CleanUserData)
Zerotorescue@0 1039 control:SetCallback("OnLeave", OptionOnMouseLeave)
Zerotorescue@0 1040 control:SetCallback("OnEnter", OptionOnMouseOver)
Zerotorescue@0 1041 end
Zerotorescue@0 1042
Zerotorescue@0 1043
Zerotorescue@0 1044 --[[
Zerotorescue@0 1045 options - root of the options table being fed
Zerotorescue@0 1046 container - widget that controls will be placed in
Zerotorescue@0 1047 rootframe - Frame object the options are in
Zerotorescue@0 1048 path - table with the keys to get to the group being fed
Zerotorescue@0 1049 --]]
Zerotorescue@0 1050
Zerotorescue@0 1051 local function FeedOptions(appName, options,container,rootframe,path,group,inline)
Zerotorescue@0 1052 local keySort = new()
Zerotorescue@0 1053 local opts = new()
Zerotorescue@0 1054
Zerotorescue@0 1055 BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
Zerotorescue@0 1056
Zerotorescue@0 1057 for i = 1, #keySort do
Zerotorescue@0 1058 local k = keySort[i]
Zerotorescue@0 1059 local v = opts[k]
Zerotorescue@0 1060 tinsert(path, k)
Zerotorescue@0 1061 local hidden = CheckOptionHidden(v, options, path, appName)
Zerotorescue@0 1062 local name = GetOptionsMemberValue("name", v, options, path, appName)
Zerotorescue@0 1063 if not hidden then
Zerotorescue@0 1064 if v.type == "group" then
Zerotorescue@0 1065 if inline or pickfirstset(v.dialogInline,v.guiInline,v.inline, false) then
Zerotorescue@0 1066 --Inline group
Zerotorescue@0 1067 local GroupContainer
Zerotorescue@0 1068 if name and name ~= "" then
Zerotorescue@0 1069 GroupContainer = gui:Create("InlineGroup")
Zerotorescue@0 1070 GroupContainer:SetTitle(name or "")
Zerotorescue@0 1071 else
Zerotorescue@0 1072 GroupContainer = gui:Create("SimpleGroup")
Zerotorescue@0 1073 end
Zerotorescue@0 1074
Zerotorescue@0 1075 GroupContainer.width = "fill"
Zerotorescue@0 1076 GroupContainer:SetLayout("flow")
Zerotorescue@0 1077 container:AddChild(GroupContainer)
Zerotorescue@0 1078 FeedOptions(appName,options,GroupContainer,rootframe,path,v,true)
Zerotorescue@0 1079 end
Zerotorescue@0 1080 else
Zerotorescue@0 1081 --Control to feed
Zerotorescue@0 1082 local control
Zerotorescue@0 1083
Zerotorescue@0 1084 local name = GetOptionsMemberValue("name", v, options, path, appName)
Zerotorescue@0 1085
Zerotorescue@0 1086 if v.type == "execute" then
Zerotorescue@0 1087
Zerotorescue@0 1088 local imageCoords = GetOptionsMemberValue("imageCoords",v, options, path, appName)
Zerotorescue@0 1089 local image, width, height = GetOptionsMemberValue("image",v, options, path, appName)
Zerotorescue@0 1090
Zerotorescue@0 1091 if type(image) == "string" then
Zerotorescue@0 1092 control = gui:Create("Icon")
Zerotorescue@0 1093 if not width then
Zerotorescue@0 1094 width = GetOptionsMemberValue("imageWidth",v, options, path, appName)
Zerotorescue@0 1095 end
Zerotorescue@0 1096 if not height then
Zerotorescue@0 1097 height = GetOptionsMemberValue("imageHeight",v, options, path, appName)
Zerotorescue@0 1098 end
Zerotorescue@0 1099 if type(imageCoords) == "table" then
Zerotorescue@0 1100 control:SetImage(image, unpack(imageCoords))
Zerotorescue@0 1101 else
Zerotorescue@0 1102 control:SetImage(image)
Zerotorescue@0 1103 end
Zerotorescue@0 1104 if type(width) ~= "number" then
Zerotorescue@0 1105 width = 32
Zerotorescue@0 1106 end
Zerotorescue@0 1107 if type(height) ~= "number" then
Zerotorescue@0 1108 height = 32
Zerotorescue@0 1109 end
Zerotorescue@0 1110 control:SetImageSize(width, height)
Zerotorescue@0 1111 control:SetLabel(name)
Zerotorescue@0 1112 else
Zerotorescue@0 1113 control = gui:Create("Button")
Zerotorescue@0 1114 control:SetText(name)
Zerotorescue@0 1115 end
Zerotorescue@0 1116 control:SetCallback("OnClick",ActivateControl)
Zerotorescue@0 1117
Zerotorescue@0 1118 elseif v.type == "input" then
Zerotorescue@0 1119 local controlType = v.dialogControl or v.control or (v.multiline and "MultiLineEditBox") or "EditBox"
Zerotorescue@0 1120 control = gui:Create(controlType)
Zerotorescue@0 1121 if not control then
Zerotorescue@0 1122 geterrorhandler()(("Invalid Custom Control Type - %s"):format(tostring(controlType)))
Zerotorescue@0 1123 control = gui:Create(v.multiline and "MultiLineEditBox" or "EditBox")
Zerotorescue@0 1124 end
Zerotorescue@0 1125
Zerotorescue@0 1126 if v.multiline and control.SetNumLines then
Zerotorescue@0 1127 control:SetNumLines(tonumber(v.multiline) or 4)
Zerotorescue@0 1128 end
Zerotorescue@0 1129 control:SetLabel(name)
Zerotorescue@0 1130 control:SetCallback("OnEnterPressed",ActivateControl)
Zerotorescue@0 1131 local text = GetOptionsMemberValue("get",v, options, path, appName)
Zerotorescue@0 1132 if type(text) ~= "string" then
Zerotorescue@0 1133 text = ""
Zerotorescue@0 1134 end
Zerotorescue@0 1135 control:SetText(text)
Zerotorescue@0 1136
Zerotorescue@0 1137 elseif v.type == "toggle" then
Zerotorescue@0 1138 control = gui:Create("CheckBox")
Zerotorescue@0 1139 control:SetLabel(name)
Zerotorescue@0 1140 control:SetTriState(v.tristate)
Zerotorescue@0 1141 local value = GetOptionsMemberValue("get",v, options, path, appName)
Zerotorescue@0 1142 control:SetValue(value)
Zerotorescue@0 1143 control:SetCallback("OnValueChanged",ActivateControl)
Zerotorescue@0 1144
Zerotorescue@0 1145 if v.descStyle == "inline" then
Zerotorescue@0 1146 local desc = GetOptionsMemberValue("desc", v, options, path, appName)
Zerotorescue@0 1147 control:SetDescription(desc)
Zerotorescue@0 1148 end
Zerotorescue@0 1149
Zerotorescue@0 1150 local image = GetOptionsMemberValue("image", v, options, path, appName)
Zerotorescue@0 1151 local imageCoords = GetOptionsMemberValue("imageCoords", v, options, path, appName)
Zerotorescue@0 1152
Zerotorescue@0 1153 if type(image) == "string" then
Zerotorescue@0 1154 if type(imageCoords) == "table" then
Zerotorescue@0 1155 control:SetImage(image, unpack(imageCoords))
Zerotorescue@0 1156 else
Zerotorescue@0 1157 control:SetImage(image)
Zerotorescue@0 1158 end
Zerotorescue@0 1159 end
Zerotorescue@0 1160 elseif v.type == "range" then
Zerotorescue@0 1161 control = gui:Create("Slider")
Zerotorescue@0 1162 control:SetLabel(name)
Zerotorescue@0 1163 control:SetSliderValues(v.softMin or v.min or 0, v.softMax or v.max or 100, v.bigStep or v.step or 0)
Zerotorescue@0 1164 control:SetIsPercent(v.isPercent)
Zerotorescue@0 1165 local value = GetOptionsMemberValue("get",v, options, path, appName)
Zerotorescue@0 1166 if type(value) ~= "number" then
Zerotorescue@0 1167 value = 0
Zerotorescue@0 1168 end
Zerotorescue@0 1169 control:SetValue(value)
Zerotorescue@0 1170 control:SetCallback("OnValueChanged",ActivateSlider)
Zerotorescue@0 1171 control:SetCallback("OnMouseUp",ActivateSlider)
Zerotorescue@0 1172
Zerotorescue@0 1173 elseif v.type == "select" then
Zerotorescue@0 1174 local values = GetOptionsMemberValue("values", v, options, path, appName)
Zerotorescue@0 1175 local controlType = v.dialogControl or v.control or "Dropdown"
Zerotorescue@0 1176 control = gui:Create(controlType)
Zerotorescue@0 1177 if not control then
Zerotorescue@0 1178 geterrorhandler()(("Invalid Custom Control Type - %s"):format(tostring(controlType)))
Zerotorescue@0 1179 control = gui:Create("Dropdown")
Zerotorescue@0 1180 end
Zerotorescue@0 1181 control:SetLabel(name)
Zerotorescue@0 1182 control:SetList(values)
Zerotorescue@0 1183 local value = GetOptionsMemberValue("get",v, options, path, appName)
Zerotorescue@0 1184 if not values[value] then
Zerotorescue@0 1185 value = nil
Zerotorescue@0 1186 end
Zerotorescue@0 1187 control:SetValue(value)
Zerotorescue@0 1188 control:SetCallback("OnValueChanged",ActivateControl)
Zerotorescue@0 1189
Zerotorescue@0 1190 elseif v.type == "multiselect" then
Zerotorescue@0 1191 local values = GetOptionsMemberValue("values", v, options, path, appName)
Zerotorescue@0 1192 local disabled = CheckOptionDisabled(v, options, path, appName)
Zerotorescue@0 1193
Zerotorescue@0 1194 local controlType = v.dialogControl or v.control
Zerotorescue@0 1195
Zerotorescue@0 1196 local valuesort = new()
Zerotorescue@0 1197 if values then
Zerotorescue@0 1198 for value, text in pairs(values) do
Zerotorescue@0 1199 tinsert(valuesort, value)
Zerotorescue@0 1200 end
Zerotorescue@0 1201 end
Zerotorescue@0 1202 tsort(valuesort)
Zerotorescue@0 1203
Zerotorescue@0 1204 if controlType then
Zerotorescue@0 1205 control = gui:Create(controlType)
Zerotorescue@0 1206 if not control then
Zerotorescue@0 1207 geterrorhandler()(("Invalid Custom Control Type - %s"):format(tostring(controlType)))
Zerotorescue@0 1208 end
Zerotorescue@0 1209 end
Zerotorescue@0 1210 if control then
Zerotorescue@0 1211 control:SetMultiselect(true)
Zerotorescue@0 1212 control:SetLabel(name)
Zerotorescue@0 1213 control:SetList(values)
Zerotorescue@0 1214 control:SetDisabled(disabled)
Zerotorescue@0 1215 control:SetCallback("OnValueChanged",ActivateControl)
Zerotorescue@0 1216 control:SetCallback("OnClosed", MultiControlOnClosed)
Zerotorescue@0 1217 local width = GetOptionsMemberValue("width",v,options,path,appName)
Zerotorescue@0 1218 if width == "double" then
Zerotorescue@0 1219 control:SetWidth(width_multiplier * 2)
Zerotorescue@0 1220 elseif width == "half" then
Zerotorescue@0 1221 control:SetWidth(width_multiplier / 2)
Zerotorescue@0 1222 elseif width == "full" then
Zerotorescue@0 1223 control.width = "fill"
Zerotorescue@0 1224 else
Zerotorescue@0 1225 control:SetWidth(width_multiplier)
Zerotorescue@0 1226 end
Zerotorescue@0 1227 --check:SetTriState(v.tristate)
Zerotorescue@0 1228 for i = 1, #valuesort do
Zerotorescue@0 1229 local key = valuesort[i]
Zerotorescue@0 1230 local value = GetOptionsMemberValue("get",v, options, path, appName, key)
Zerotorescue@0 1231 control:SetItemValue(key,value)
Zerotorescue@0 1232 end
Zerotorescue@0 1233 else
Zerotorescue@0 1234 control = gui:Create("InlineGroup")
Zerotorescue@0 1235 control:SetLayout("Flow")
Zerotorescue@0 1236 control:SetTitle(name)
Zerotorescue@0 1237 control.width = "fill"
Zerotorescue@0 1238
Zerotorescue@0 1239 control:PauseLayout()
Zerotorescue@0 1240 local width = GetOptionsMemberValue("width",v,options,path,appName)
Zerotorescue@0 1241 for i = 1, #valuesort do
Zerotorescue@0 1242 local value = valuesort[i]
Zerotorescue@0 1243 local text = values[value]
Zerotorescue@0 1244 local check = gui:Create("CheckBox")
Zerotorescue@0 1245 check:SetLabel(text)
Zerotorescue@0 1246 check:SetUserData("value", value)
Zerotorescue@0 1247 check:SetUserData("text", text)
Zerotorescue@0 1248 check:SetDisabled(disabled)
Zerotorescue@0 1249 check:SetTriState(v.tristate)
Zerotorescue@0 1250 check:SetValue(GetOptionsMemberValue("get",v, options, path, appName, value))
Zerotorescue@0 1251 check:SetCallback("OnValueChanged",ActivateMultiControl)
Zerotorescue@0 1252 InjectInfo(check, options, v, path, rootframe, appName)
Zerotorescue@0 1253 control:AddChild(check)
Zerotorescue@0 1254 if width == "double" then
Zerotorescue@0 1255 check:SetWidth(width_multiplier * 2)
Zerotorescue@0 1256 elseif width == "half" then
Zerotorescue@0 1257 check:SetWidth(width_multiplier / 2)
Zerotorescue@0 1258 elseif width == "full" then
Zerotorescue@0 1259 check.width = "fill"
Zerotorescue@0 1260 else
Zerotorescue@0 1261 check:SetWidth(width_multiplier)
Zerotorescue@0 1262 end
Zerotorescue@0 1263 end
Zerotorescue@0 1264 control:ResumeLayout()
Zerotorescue@0 1265 control:DoLayout()
Zerotorescue@0 1266
Zerotorescue@0 1267
Zerotorescue@0 1268 end
Zerotorescue@0 1269
Zerotorescue@0 1270 del(valuesort)
Zerotorescue@0 1271
Zerotorescue@0 1272 elseif v.type == "color" then
Zerotorescue@0 1273 control = gui:Create("ColorPicker")
Zerotorescue@0 1274 control:SetLabel(name)
Zerotorescue@0 1275 control:SetHasAlpha(v.hasAlpha)
Zerotorescue@0 1276 control:SetColor(GetOptionsMemberValue("get",v, options, path, appName))
Zerotorescue@0 1277 control:SetCallback("OnValueChanged",ActivateControl)
Zerotorescue@0 1278 control:SetCallback("OnValueConfirmed",ActivateControl)
Zerotorescue@0 1279
Zerotorescue@0 1280 elseif v.type == "keybinding" then
Zerotorescue@0 1281 control = gui:Create("Keybinding")
Zerotorescue@0 1282 control:SetLabel(name)
Zerotorescue@0 1283 control:SetKey(GetOptionsMemberValue("get",v, options, path, appName))
Zerotorescue@0 1284 control:SetCallback("OnKeyChanged",ActivateControl)
Zerotorescue@0 1285
Zerotorescue@0 1286 elseif v.type == "header" then
Zerotorescue@0 1287 control = gui:Create("Heading")
Zerotorescue@0 1288 control:SetText(name)
Zerotorescue@0 1289 control.width = "fill"
Zerotorescue@0 1290
Zerotorescue@0 1291 elseif v.type == "description" then
Zerotorescue@0 1292 control = gui:Create("Label")
Zerotorescue@0 1293 control:SetText(name)
Zerotorescue@0 1294
Zerotorescue@0 1295 local fontSize = GetOptionsMemberValue("fontSize",v, options, path, appName)
Zerotorescue@0 1296 if fontSize == "medium" then
Zerotorescue@0 1297 control:SetFontObject(GameFontHighlight)
Zerotorescue@0 1298 elseif fontSize == "large" then
Zerotorescue@0 1299 control:SetFontObject(GameFontHighlightLarge)
Zerotorescue@0 1300 else -- small or invalid
Zerotorescue@0 1301 control:SetFontObject(GameFontHighlightSmall)
Zerotorescue@0 1302 end
Zerotorescue@0 1303
Zerotorescue@0 1304 local imageCoords = GetOptionsMemberValue("imageCoords",v, options, path, appName)
Zerotorescue@0 1305 local image, width, height = GetOptionsMemberValue("image",v, options, path, appName)
Zerotorescue@0 1306
Zerotorescue@0 1307 if type(image) == "string" then
Zerotorescue@0 1308 if not width then
Zerotorescue@0 1309 width = GetOptionsMemberValue("imageWidth",v, options, path, appName)
Zerotorescue@0 1310 end
Zerotorescue@0 1311 if not height then
Zerotorescue@0 1312 height = GetOptionsMemberValue("imageHeight",v, options, path, appName)
Zerotorescue@0 1313 end
Zerotorescue@0 1314 if type(imageCoords) == "table" then
Zerotorescue@0 1315 control:SetImage(image, unpack(imageCoords))
Zerotorescue@0 1316 else
Zerotorescue@0 1317 control:SetImage(image)
Zerotorescue@0 1318 end
Zerotorescue@0 1319 if type(width) ~= "number" then
Zerotorescue@0 1320 width = 32
Zerotorescue@0 1321 end
Zerotorescue@0 1322 if type(height) ~= "number" then
Zerotorescue@0 1323 height = 32
Zerotorescue@0 1324 end
Zerotorescue@0 1325 control:SetImageSize(width, height)
Zerotorescue@0 1326 end
Zerotorescue@0 1327 local width = GetOptionsMemberValue("width",v,options,path,appName)
Zerotorescue@0 1328 control.width = not width and "fill"
Zerotorescue@0 1329 end
Zerotorescue@0 1330
Zerotorescue@0 1331 --Common Init
Zerotorescue@0 1332 if control then
Zerotorescue@0 1333 if control.width ~= "fill" then
Zerotorescue@0 1334 local width = GetOptionsMemberValue("width",v,options,path,appName)
Zerotorescue@0 1335 if width == "double" then
Zerotorescue@0 1336 control:SetWidth(width_multiplier * 2)
Zerotorescue@0 1337 elseif width == "half" then
Zerotorescue@0 1338 control:SetWidth(width_multiplier / 2)
Zerotorescue@0 1339 elseif width == "full" then
Zerotorescue@0 1340 control.width = "fill"
Zerotorescue@0 1341 else
Zerotorescue@0 1342 control:SetWidth(width_multiplier)
Zerotorescue@0 1343 end
Zerotorescue@0 1344 end
Zerotorescue@0 1345 if control.SetDisabled then
Zerotorescue@0 1346 local disabled = CheckOptionDisabled(v, options, path, appName)
Zerotorescue@0 1347 control:SetDisabled(disabled)
Zerotorescue@0 1348 end
Zerotorescue@0 1349
Zerotorescue@0 1350 InjectInfo(control, options, v, path, rootframe, appName)
Zerotorescue@0 1351 container:AddChild(control)
Zerotorescue@0 1352 end
Zerotorescue@0 1353
Zerotorescue@0 1354 end
Zerotorescue@0 1355 end
Zerotorescue@0 1356 tremove(path)
Zerotorescue@0 1357 end
Zerotorescue@0 1358 container:ResumeLayout()
Zerotorescue@0 1359 container:DoLayout()
Zerotorescue@0 1360 del(keySort)
Zerotorescue@0 1361 del(opts)
Zerotorescue@0 1362 end
Zerotorescue@0 1363
Zerotorescue@0 1364 local function BuildPath(path, ...)
Zerotorescue@0 1365 for i = 1, select("#",...) do
Zerotorescue@0 1366 tinsert(path, (select(i,...)))
Zerotorescue@0 1367 end
Zerotorescue@0 1368 end
Zerotorescue@0 1369
Zerotorescue@0 1370
Zerotorescue@0 1371 local function TreeOnButtonEnter(widget, event, uniquevalue, button)
Zerotorescue@0 1372 local user = widget:GetUserDataTable()
Zerotorescue@0 1373 if not user then return end
Zerotorescue@0 1374 local options = user.options
Zerotorescue@0 1375 local option = user.option
Zerotorescue@0 1376 local path = user.path
Zerotorescue@0 1377 local appName = user.appName
Zerotorescue@0 1378
Zerotorescue@0 1379 local feedpath = new()
Zerotorescue@0 1380 for i = 1, #path do
Zerotorescue@0 1381 feedpath[i] = path[i]
Zerotorescue@0 1382 end
Zerotorescue@0 1383
Zerotorescue@0 1384 BuildPath(feedpath, ("\001"):split(uniquevalue))
Zerotorescue@0 1385 local group = options
Zerotorescue@0 1386 for i = 1, #feedpath do
Zerotorescue@0 1387 if not group then return end
Zerotorescue@0 1388 group = GetSubOption(group, feedpath[i])
Zerotorescue@0 1389 end
Zerotorescue@0 1390
Zerotorescue@0 1391 local name = GetOptionsMemberValue("name", group, options, feedpath, appName)
Zerotorescue@0 1392 local desc = GetOptionsMemberValue("desc", group, options, feedpath, appName)
Zerotorescue@0 1393
Zerotorescue@0 1394 GameTooltip:SetOwner(button, "ANCHOR_NONE")
Zerotorescue@0 1395 if widget.type == "TabGroup" then
Zerotorescue@0 1396 GameTooltip:SetPoint("BOTTOM",button,"TOP")
Zerotorescue@0 1397 else
Zerotorescue@0 1398 GameTooltip:SetPoint("LEFT",button,"RIGHT")
Zerotorescue@0 1399 end
Zerotorescue@0 1400
Zerotorescue@0 1401 GameTooltip:SetText(name, 1, .82, 0, 1)
Zerotorescue@0 1402
Zerotorescue@0 1403 if type(desc) == "string" then
Zerotorescue@0 1404 GameTooltip:AddLine(desc, 1, 1, 1, 1)
Zerotorescue@0 1405 end
Zerotorescue@0 1406
Zerotorescue@0 1407 GameTooltip:Show()
Zerotorescue@0 1408 end
Zerotorescue@0 1409
Zerotorescue@0 1410 local function TreeOnButtonLeave(widget, event, value, button)
Zerotorescue@0 1411 GameTooltip:Hide()
Zerotorescue@0 1412 end
Zerotorescue@0 1413
Zerotorescue@0 1414
Zerotorescue@0 1415 local function GroupExists(appName, options, path, uniquevalue)
Zerotorescue@0 1416 if not uniquevalue then return false end
Zerotorescue@0 1417
Zerotorescue@0 1418 local feedpath = new()
Zerotorescue@0 1419 local temppath = new()
Zerotorescue@0 1420 for i = 1, #path do
Zerotorescue@0 1421 feedpath[i] = path[i]
Zerotorescue@0 1422 end
Zerotorescue@0 1423
Zerotorescue@0 1424 BuildPath(feedpath, ("\001"):split(uniquevalue))
Zerotorescue@0 1425
Zerotorescue@0 1426 local group = options
Zerotorescue@0 1427 for i = 1, #feedpath do
Zerotorescue@0 1428 local v = feedpath[i]
Zerotorescue@0 1429 temppath[i] = v
Zerotorescue@0 1430 group = GetSubOption(group, v)
Zerotorescue@0 1431
Zerotorescue@0 1432 if not group or group.type ~= "group" or CheckOptionHidden(group, options, temppath, appName) then
Zerotorescue@0 1433 del(feedpath)
Zerotorescue@0 1434 del(temppath)
Zerotorescue@0 1435 return false
Zerotorescue@0 1436 end
Zerotorescue@0 1437 end
Zerotorescue@0 1438 del(feedpath)
Zerotorescue@0 1439 del(temppath)
Zerotorescue@0 1440 return true
Zerotorescue@0 1441 end
Zerotorescue@0 1442
Zerotorescue@0 1443 local function GroupSelected(widget, event, uniquevalue)
Zerotorescue@0 1444
Zerotorescue@0 1445 local user = widget:GetUserDataTable()
Zerotorescue@0 1446
Zerotorescue@0 1447 local options = user.options
Zerotorescue@0 1448 local option = user.option
Zerotorescue@0 1449 local path = user.path
Zerotorescue@0 1450 local rootframe = user.rootframe
Zerotorescue@0 1451
Zerotorescue@0 1452 local feedpath = new()
Zerotorescue@0 1453 for i = 1, #path do
Zerotorescue@0 1454 feedpath[i] = path[i]
Zerotorescue@0 1455 end
Zerotorescue@0 1456
Zerotorescue@0 1457 BuildPath(feedpath, ("\001"):split(uniquevalue))
Zerotorescue@0 1458 local group = options
Zerotorescue@0 1459 for i = 1, #feedpath do
Zerotorescue@0 1460 group = GetSubOption(group, feedpath[i])
Zerotorescue@0 1461 end
Zerotorescue@0 1462 widget:ReleaseChildren()
Zerotorescue@0 1463 AceConfigDialog:FeedGroup(user.appName,options,widget,rootframe,feedpath)
Zerotorescue@0 1464
Zerotorescue@0 1465 del(feedpath)
Zerotorescue@0 1466 end
Zerotorescue@0 1467
Zerotorescue@0 1468
Zerotorescue@0 1469
Zerotorescue@0 1470 --[[
Zerotorescue@0 1471 -- INTERNAL --
Zerotorescue@0 1472 This function will feed one group, and any inline child groups into the given container
Zerotorescue@0 1473 Select Groups will only have the selection control (tree, tabs, dropdown) fed in
Zerotorescue@0 1474 and have a group selected, this event will trigger the feeding of child groups
Zerotorescue@0 1475
Zerotorescue@0 1476 Rules:
Zerotorescue@0 1477 If the group is Inline, FeedOptions
Zerotorescue@0 1478 If the group has no child groups, FeedOptions
Zerotorescue@0 1479
Zerotorescue@0 1480 If the group is a tab or select group, FeedOptions then add the Group Control
Zerotorescue@0 1481 If the group is a tree group FeedOptions then
Zerotorescue@0 1482 its parent isnt a tree group: then add the tree control containing this and all child tree groups
Zerotorescue@0 1483 if its parent is a tree group, its already a node on a tree
Zerotorescue@0 1484 --]]
Zerotorescue@0 1485
Zerotorescue@0 1486 function AceConfigDialog:FeedGroup(appName,options,container,rootframe,path, isRoot)
Zerotorescue@0 1487 local group = options
Zerotorescue@0 1488 --follow the path to get to the curent group
Zerotorescue@0 1489 local inline
Zerotorescue@0 1490 local grouptype, parenttype = options.childGroups, "none"
Zerotorescue@0 1491
Zerotorescue@0 1492
Zerotorescue@0 1493 for i = 1, #path do
Zerotorescue@0 1494 local v = path[i]
Zerotorescue@0 1495 group = GetSubOption(group, v)
Zerotorescue@0 1496 inline = inline or pickfirstset(v.dialogInline,v.guiInline,v.inline, false)
Zerotorescue@0 1497 parenttype = grouptype
Zerotorescue@0 1498 grouptype = group.childGroups
Zerotorescue@0 1499 end
Zerotorescue@0 1500
Zerotorescue@0 1501 if not parenttype then
Zerotorescue@0 1502 parenttype = "tree"
Zerotorescue@0 1503 end
Zerotorescue@0 1504
Zerotorescue@0 1505 --check if the group has child groups
Zerotorescue@0 1506 local hasChildGroups
Zerotorescue@0 1507 for k, v in pairs(group.args) do
Zerotorescue@0 1508 if v.type == "group" and not pickfirstset(v.dialogInline,v.guiInline,v.inline, false) and not CheckOptionHidden(v, options, path, appName) then
Zerotorescue@0 1509 hasChildGroups = true
Zerotorescue@0 1510 end
Zerotorescue@0 1511 end
Zerotorescue@0 1512 if group.plugins then
Zerotorescue@0 1513 for plugin, t in pairs(group.plugins) do
Zerotorescue@0 1514 for k, v in pairs(t) do
Zerotorescue@0 1515 if v.type == "group" and not pickfirstset(v.dialogInline,v.guiInline,v.inline, false) and not CheckOptionHidden(v, options, path, appName) then
Zerotorescue@0 1516 hasChildGroups = true
Zerotorescue@0 1517 end
Zerotorescue@0 1518 end
Zerotorescue@0 1519 end
Zerotorescue@0 1520 end
Zerotorescue@0 1521
Zerotorescue@0 1522 container:SetLayout("flow")
Zerotorescue@0 1523 local scroll
Zerotorescue@0 1524
Zerotorescue@0 1525 --Add a scrollframe if we are not going to add a group control, this is the inverse of the conditions for that later on
Zerotorescue@0 1526 if (not (hasChildGroups and not inline)) or (grouptype ~= "tab" and grouptype ~= "select" and (parenttype == "tree" and not isRoot)) then
Zerotorescue@0 1527 if container.type ~= "InlineGroup" and container.type ~= "SimpleGroup" then
Zerotorescue@0 1528 scroll = gui:Create("ScrollFrame")
Zerotorescue@0 1529 scroll:SetLayout("flow")
Zerotorescue@0 1530 scroll.width = "fill"
Zerotorescue@0 1531 scroll.height = "fill"
Zerotorescue@0 1532 container:SetLayout("fill")
Zerotorescue@0 1533 container:AddChild(scroll)
Zerotorescue@0 1534 container = scroll
Zerotorescue@0 1535 end
Zerotorescue@0 1536 end
Zerotorescue@0 1537
Zerotorescue@0 1538 FeedOptions(appName,options,container,rootframe,path,group,nil)
Zerotorescue@0 1539
Zerotorescue@0 1540 if scroll then
Zerotorescue@0 1541 container:PerformLayout()
Zerotorescue@0 1542 local status = self:GetStatusTable(appName, path)
Zerotorescue@0 1543 if not status.scroll then
Zerotorescue@0 1544 status.scroll = {}
Zerotorescue@0 1545 end
Zerotorescue@0 1546 scroll:SetStatusTable(status.scroll)
Zerotorescue@0 1547 end
Zerotorescue@0 1548
Zerotorescue@0 1549 if hasChildGroups and not inline then
Zerotorescue@0 1550 local name = GetOptionsMemberValue("name", group, options, path, appName)
Zerotorescue@0 1551 if grouptype == "tab" then
Zerotorescue@0 1552
Zerotorescue@0 1553 local tab = gui:Create("TabGroup")
Zerotorescue@0 1554 InjectInfo(tab, options, group, path, rootframe, appName)
Zerotorescue@0 1555 tab:SetCallback("OnGroupSelected", GroupSelected)
Zerotorescue@0 1556 tab:SetCallback("OnTabEnter", TreeOnButtonEnter)
Zerotorescue@0 1557 tab:SetCallback("OnTabLeave", TreeOnButtonLeave)
Zerotorescue@0 1558
Zerotorescue@0 1559 local status = AceConfigDialog:GetStatusTable(appName, path)
Zerotorescue@0 1560 if not status.groups then
Zerotorescue@0 1561 status.groups = {}
Zerotorescue@0 1562 end
Zerotorescue@0 1563 tab:SetStatusTable(status.groups)
Zerotorescue@0 1564 tab.width = "fill"
Zerotorescue@0 1565 tab.height = "fill"
Zerotorescue@0 1566
Zerotorescue@0 1567 local tabs = BuildGroups(group, options, path, appName)
Zerotorescue@0 1568 tab:SetTabs(tabs)
Zerotorescue@0 1569 tab:SetUserData("tablist", tabs)
Zerotorescue@0 1570
Zerotorescue@0 1571 for i = 1, #tabs do
Zerotorescue@0 1572 local entry = tabs[i]
Zerotorescue@0 1573 if not entry.disabled then
Zerotorescue@0 1574 tab:SelectTab((GroupExists(appName, options, path,status.groups.selected) and status.groups.selected) or entry.value)
Zerotorescue@0 1575 break
Zerotorescue@0 1576 end
Zerotorescue@0 1577 end
Zerotorescue@0 1578
Zerotorescue@0 1579 container:AddChild(tab)
Zerotorescue@0 1580
Zerotorescue@0 1581 elseif grouptype == "select" then
Zerotorescue@0 1582
Zerotorescue@0 1583 local select = gui:Create("DropdownGroup")
Zerotorescue@0 1584 select:SetTitle(name)
Zerotorescue@0 1585 InjectInfo(select, options, group, path, rootframe, appName)
Zerotorescue@0 1586 select:SetCallback("OnGroupSelected", GroupSelected)
Zerotorescue@0 1587 local status = AceConfigDialog:GetStatusTable(appName, path)
Zerotorescue@0 1588 if not status.groups then
Zerotorescue@0 1589 status.groups = {}
Zerotorescue@0 1590 end
Zerotorescue@0 1591 select:SetStatusTable(status.groups)
Zerotorescue@0 1592 local grouplist = BuildSelect(group, options, path, appName)
Zerotorescue@0 1593 select:SetGroupList(grouplist)
Zerotorescue@0 1594 select:SetUserData("grouplist", grouplist)
Zerotorescue@0 1595 local firstgroup
Zerotorescue@0 1596 for k, v in pairs(grouplist) do
Zerotorescue@0 1597 if not firstgroup or k < firstgroup then
Zerotorescue@0 1598 firstgroup = k
Zerotorescue@0 1599 end
Zerotorescue@0 1600 end
Zerotorescue@0 1601
Zerotorescue@0 1602 if firstgroup then
Zerotorescue@0 1603 select:SetGroup((GroupExists(appName, options, path,status.groups.selected) and status.groups.selected) or firstgroup)
Zerotorescue@0 1604 end
Zerotorescue@0 1605
Zerotorescue@0 1606 select.width = "fill"
Zerotorescue@0 1607 select.height = "fill"
Zerotorescue@0 1608
Zerotorescue@0 1609 container:AddChild(select)
Zerotorescue@0 1610
Zerotorescue@0 1611 --assume tree group by default
Zerotorescue@0 1612 --if parenttype is tree then this group is already a node on that tree
Zerotorescue@0 1613 elseif (parenttype ~= "tree") or isRoot then
Zerotorescue@0 1614 local tree = gui:Create("TreeGroup")
Zerotorescue@0 1615 InjectInfo(tree, options, group, path, rootframe, appName)
Zerotorescue@0 1616 tree:EnableButtonTooltips(false)
Zerotorescue@0 1617
Zerotorescue@0 1618 tree.width = "fill"
Zerotorescue@0 1619 tree.height = "fill"
Zerotorescue@0 1620
Zerotorescue@0 1621 tree:SetCallback("OnGroupSelected", GroupSelected)
Zerotorescue@0 1622 tree:SetCallback("OnButtonEnter", TreeOnButtonEnter)
Zerotorescue@0 1623 tree:SetCallback("OnButtonLeave", TreeOnButtonLeave)
Zerotorescue@0 1624
Zerotorescue@0 1625 local status = AceConfigDialog:GetStatusTable(appName, path)
Zerotorescue@0 1626 if not status.groups then
Zerotorescue@0 1627 status.groups = {}
Zerotorescue@0 1628 end
Zerotorescue@0 1629 local treedefinition = BuildGroups(group, options, path, appName, true)
Zerotorescue@0 1630 tree:SetStatusTable(status.groups)
Zerotorescue@0 1631
Zerotorescue@0 1632 tree:SetTree(treedefinition)
Zerotorescue@0 1633 tree:SetUserData("tree",treedefinition)
Zerotorescue@0 1634
Zerotorescue@0 1635 for i = 1, #treedefinition do
Zerotorescue@0 1636 local entry = treedefinition[i]
Zerotorescue@0 1637 if not entry.disabled then
Zerotorescue@0 1638 tree:SelectByValue((GroupExists(appName, options, path,status.groups.selected) and status.groups.selected) or entry.value)
Zerotorescue@0 1639 break
Zerotorescue@0 1640 end
Zerotorescue@0 1641 end
Zerotorescue@0 1642
Zerotorescue@0 1643 container:AddChild(tree)
Zerotorescue@0 1644 end
Zerotorescue@0 1645 end
Zerotorescue@0 1646 end
Zerotorescue@0 1647
Zerotorescue@0 1648 local old_CloseSpecialWindows
Zerotorescue@0 1649
Zerotorescue@0 1650
Zerotorescue@0 1651 local function RefreshOnUpdate(this)
Zerotorescue@0 1652 for appName in pairs(this.closing) do
Zerotorescue@0 1653 if AceConfigDialog.OpenFrames[appName] then
Zerotorescue@0 1654 AceConfigDialog.OpenFrames[appName]:Hide()
Zerotorescue@0 1655 end
Zerotorescue@0 1656 if AceConfigDialog.BlizOptions and AceConfigDialog.BlizOptions[appName] then
Zerotorescue@0 1657 for key, widget in pairs(AceConfigDialog.BlizOptions[appName]) do
Zerotorescue@0 1658 if not widget:IsVisible() then
Zerotorescue@0 1659 widget:ReleaseChildren()
Zerotorescue@0 1660 end
Zerotorescue@0 1661 end
Zerotorescue@0 1662 end
Zerotorescue@0 1663 this.closing[appName] = nil
Zerotorescue@0 1664 end
Zerotorescue@0 1665
Zerotorescue@0 1666 if this.closeAll then
Zerotorescue@0 1667 for k, v in pairs(AceConfigDialog.OpenFrames) do
Zerotorescue@0 1668 if not this.closeAllOverride[k] then
Zerotorescue@0 1669 v:Hide()
Zerotorescue@0 1670 end
Zerotorescue@0 1671 end
Zerotorescue@0 1672 this.closeAll = nil
Zerotorescue@0 1673 wipe(this.closeAllOverride)
Zerotorescue@0 1674 end
Zerotorescue@0 1675
Zerotorescue@0 1676 for appName in pairs(this.apps) do
Zerotorescue@0 1677 if AceConfigDialog.OpenFrames[appName] then
Zerotorescue@0 1678 local user = AceConfigDialog.OpenFrames[appName]:GetUserDataTable()
Zerotorescue@0 1679 AceConfigDialog:Open(appName, unpack(user.basepath or emptyTbl))
Zerotorescue@0 1680 end
Zerotorescue@0 1681 if AceConfigDialog.BlizOptions and AceConfigDialog.BlizOptions[appName] then
Zerotorescue@0 1682 for key, widget in pairs(AceConfigDialog.BlizOptions[appName]) do
Zerotorescue@0 1683 local user = widget:GetUserDataTable()
Zerotorescue@0 1684 if widget:IsVisible() then
Zerotorescue@0 1685 AceConfigDialog:Open(widget:GetUserData("appName"), widget, unpack(user.basepath or emptyTbl))
Zerotorescue@0 1686 end
Zerotorescue@0 1687 end
Zerotorescue@0 1688 end
Zerotorescue@0 1689 this.apps[appName] = nil
Zerotorescue@0 1690 end
Zerotorescue@0 1691 this:SetScript("OnUpdate", nil)
Zerotorescue@0 1692 end
Zerotorescue@0 1693
Zerotorescue@0 1694 -- Upgrade the OnUpdate script as well, if needed.
Zerotorescue@0 1695 if AceConfigDialog.frame:GetScript("OnUpdate") then
Zerotorescue@0 1696 AceConfigDialog.frame:SetScript("OnUpdate", RefreshOnUpdate)
Zerotorescue@0 1697 end
Zerotorescue@0 1698
Zerotorescue@0 1699 --- Close all open options windows
Zerotorescue@0 1700 function AceConfigDialog:CloseAll()
Zerotorescue@0 1701 AceConfigDialog.frame.closeAll = true
Zerotorescue@0 1702 AceConfigDialog.frame:SetScript("OnUpdate", RefreshOnUpdate)
Zerotorescue@0 1703 if next(self.OpenFrames) then
Zerotorescue@0 1704 return true
Zerotorescue@0 1705 end
Zerotorescue@0 1706 end
Zerotorescue@0 1707
Zerotorescue@0 1708 --- Close a specific options window.
Zerotorescue@0 1709 -- @param appName The application name as given to `:RegisterOptionsTable()`
Zerotorescue@0 1710 function AceConfigDialog:Close(appName)
Zerotorescue@0 1711 if self.OpenFrames[appName] then
Zerotorescue@0 1712 AceConfigDialog.frame.closing[appName] = true
Zerotorescue@0 1713 AceConfigDialog.frame:SetScript("OnUpdate", RefreshOnUpdate)
Zerotorescue@0 1714 return true
Zerotorescue@0 1715 end
Zerotorescue@0 1716 end
Zerotorescue@0 1717
Zerotorescue@0 1718 -- Internal -- Called by AceConfigRegistry
Zerotorescue@0 1719 function AceConfigDialog:ConfigTableChanged(event, appName)
Zerotorescue@0 1720 AceConfigDialog.frame.apps[appName] = true
Zerotorescue@0 1721 AceConfigDialog.frame:SetScript("OnUpdate", RefreshOnUpdate)
Zerotorescue@0 1722 end
Zerotorescue@0 1723
Zerotorescue@0 1724 reg.RegisterCallback(AceConfigDialog, "ConfigTableChange", "ConfigTableChanged")
Zerotorescue@0 1725
Zerotorescue@0 1726 --- Sets the default size of the options window for a specific application.
Zerotorescue@0 1727 -- @param appName The application name as given to `:RegisterOptionsTable()`
Zerotorescue@0 1728 -- @param width The default width
Zerotorescue@0 1729 -- @param height The default height
Zerotorescue@0 1730 function AceConfigDialog:SetDefaultSize(appName, width, height)
Zerotorescue@0 1731 local status = AceConfigDialog:GetStatusTable(appName)
Zerotorescue@0 1732 if type(width) == "number" and type(height) == "number" then
Zerotorescue@0 1733 status.width = width
Zerotorescue@0 1734 status.height = height
Zerotorescue@0 1735 end
Zerotorescue@0 1736 end
Zerotorescue@0 1737
Zerotorescue@0 1738 --- Open an option window at the specified path (if any).
Zerotorescue@0 1739 -- This function can optionally feed the group into a pre-created container
Zerotorescue@0 1740 -- instead of creating a new container frame.
Zerotorescue@0 1741 -- @paramsig appName [, container][, ...]
Zerotorescue@0 1742 -- @param appName The application name as given to `:RegisterOptionsTable()`
Zerotorescue@0 1743 -- @param container An optional container frame to feed the options into
Zerotorescue@0 1744 -- @param ... The path to open after creating the options window (see `:SelectGroup` for details)
Zerotorescue@0 1745 function AceConfigDialog:Open(appName, container, ...)
Zerotorescue@0 1746 if not old_CloseSpecialWindows then
Zerotorescue@0 1747 old_CloseSpecialWindows = CloseSpecialWindows
Zerotorescue@0 1748 CloseSpecialWindows = function()
Zerotorescue@0 1749 local found = old_CloseSpecialWindows()
Zerotorescue@0 1750 return self:CloseAll() or found
Zerotorescue@0 1751 end
Zerotorescue@0 1752 end
Zerotorescue@0 1753 local app = reg:GetOptionsTable(appName)
Zerotorescue@0 1754 if not app then
Zerotorescue@0 1755 error(("%s isn't registed with AceConfigRegistry, unable to open config"):format(appName), 2)
Zerotorescue@0 1756 end
Zerotorescue@0 1757 local options = app("dialog", MAJOR)
Zerotorescue@0 1758
Zerotorescue@0 1759 local f
Zerotorescue@0 1760
Zerotorescue@0 1761 local path = new()
Zerotorescue@0 1762 local name = GetOptionsMemberValue("name", options, options, path, appName)
Zerotorescue@0 1763
Zerotorescue@0 1764 --If an optional path is specified add it to the path table before feeding the options
Zerotorescue@0 1765 --as container is optional as well it may contain the first element of the path
Zerotorescue@0 1766 if type(container) == "string" then
Zerotorescue@0 1767 tinsert(path, container)
Zerotorescue@0 1768 container = nil
Zerotorescue@0 1769 end
Zerotorescue@0 1770 for n = 1, select("#",...) do
Zerotorescue@0 1771 tinsert(path, (select(n, ...)))
Zerotorescue@0 1772 end
Zerotorescue@0 1773
Zerotorescue@0 1774 --if a container is given feed into that
Zerotorescue@0 1775 if container then
Zerotorescue@0 1776 f = container
Zerotorescue@0 1777 f:ReleaseChildren()
Zerotorescue@0 1778 f:SetUserData("appName", appName)
Zerotorescue@0 1779 f:SetUserData("iscustom", true)
Zerotorescue@0 1780 if #path > 0 then
Zerotorescue@0 1781 f:SetUserData("basepath", copy(path))
Zerotorescue@0 1782 end
Zerotorescue@0 1783 local status = AceConfigDialog:GetStatusTable(appName)
Zerotorescue@0 1784 if not status.width then
Zerotorescue@0 1785 status.width = 700
Zerotorescue@0 1786 end
Zerotorescue@0 1787 if not status.height then
Zerotorescue@0 1788 status.height = 500
Zerotorescue@0 1789 end
Zerotorescue@0 1790 if f.SetStatusTable then
Zerotorescue@0 1791 f:SetStatusTable(status)
Zerotorescue@0 1792 end
Zerotorescue@0 1793 if f.SetTitle then
Zerotorescue@0 1794 f:SetTitle(name or "")
Zerotorescue@0 1795 end
Zerotorescue@0 1796 else
Zerotorescue@0 1797 if not self.OpenFrames[appName] then
Zerotorescue@0 1798 f = gui:Create("Frame")
Zerotorescue@0 1799 self.OpenFrames[appName] = f
Zerotorescue@0 1800 else
Zerotorescue@0 1801 f = self.OpenFrames[appName]
Zerotorescue@0 1802 end
Zerotorescue@0 1803 f:ReleaseChildren()
Zerotorescue@0 1804 f:SetCallback("OnClose", FrameOnClose)
Zerotorescue@0 1805 f:SetUserData("appName", appName)
Zerotorescue@0 1806 if #path > 0 then
Zerotorescue@0 1807 f:SetUserData("basepath", copy(path))
Zerotorescue@0 1808 end
Zerotorescue@0 1809 f:SetTitle(name or "")
Zerotorescue@0 1810 local status = AceConfigDialog:GetStatusTable(appName)
Zerotorescue@0 1811 f:SetStatusTable(status)
Zerotorescue@0 1812 end
Zerotorescue@0 1813
Zerotorescue@0 1814 self:FeedGroup(appName,options,f,f,path,true)
Zerotorescue@0 1815 if f.Show then
Zerotorescue@0 1816 f:Show()
Zerotorescue@0 1817 end
Zerotorescue@0 1818 del(path)
Zerotorescue@0 1819
Zerotorescue@0 1820 if AceConfigDialog.frame.closeAll then
Zerotorescue@0 1821 -- close all is set, but thats not good, since we're just opening here, so force it
Zerotorescue@0 1822 AceConfigDialog.frame.closeAllOverride[appName] = true
Zerotorescue@0 1823 end
Zerotorescue@0 1824 end
Zerotorescue@0 1825
Zerotorescue@0 1826 -- convert pre-39 BlizOptions structure to the new format
Zerotorescue@0 1827 if oldminor and oldminor < 39 and AceConfigDialog.BlizOptions then
Zerotorescue@0 1828 local old = AceConfigDialog.BlizOptions
Zerotorescue@0 1829 local new = {}
Zerotorescue@0 1830 for key, widget in pairs(old) do
Zerotorescue@0 1831 local appName = widget:GetUserData("appName")
Zerotorescue@0 1832 if not new[appName] then new[appName] = {} end
Zerotorescue@0 1833 new[appName][key] = widget
Zerotorescue@0 1834 end
Zerotorescue@0 1835 AceConfigDialog.BlizOptions = new
Zerotorescue@0 1836 else
Zerotorescue@0 1837 AceConfigDialog.BlizOptions = AceConfigDialog.BlizOptions or {}
Zerotorescue@0 1838 end
Zerotorescue@0 1839
Zerotorescue@0 1840 local function FeedToBlizPanel(widget, event)
Zerotorescue@0 1841 local path = widget:GetUserData("path")
Zerotorescue@0 1842 AceConfigDialog:Open(widget:GetUserData("appName"), widget, unpack(path or emptyTbl))
Zerotorescue@0 1843 end
Zerotorescue@0 1844
Zerotorescue@0 1845 local function ClearBlizPanel(widget, event)
Zerotorescue@0 1846 local appName = widget:GetUserData("appName")
Zerotorescue@0 1847 AceConfigDialog.frame.closing[appName] = true
Zerotorescue@0 1848 AceConfigDialog.frame:SetScript("OnUpdate", RefreshOnUpdate)
Zerotorescue@0 1849 end
Zerotorescue@0 1850
Zerotorescue@0 1851 --- Add an option table into the Blizzard Interface Options panel.
Zerotorescue@0 1852 -- You can optionally supply a descriptive name to use and a parent frame to use,
Zerotorescue@0 1853 -- as well as a path in the options table.\\
Zerotorescue@0 1854 -- If no name is specified, the appName will be used instead.
Zerotorescue@0 1855 --
Zerotorescue@0 1856 -- If you specify a proper `parent` (by name), the interface options will generate a
Zerotorescue@0 1857 -- tree layout. Note that only one level of children is supported, so the parent always
Zerotorescue@0 1858 -- has to be a head-level note.
Zerotorescue@0 1859 --
Zerotorescue@0 1860 -- This function returns a reference to the container frame registered with the Interface
Zerotorescue@0 1861 -- Options. You can use this reference to open the options with the API function
Zerotorescue@0 1862 -- `InterfaceOptionsFrame_OpenToCategory`.
Zerotorescue@0 1863 -- @param appName The application name as given to `:RegisterOptionsTable()`
Zerotorescue@0 1864 -- @param name A descriptive name to display in the options tree (defaults to appName)
Zerotorescue@0 1865 -- @param parent The parent to use in the interface options tree.
Zerotorescue@0 1866 -- @param ... The path in the options table to feed into the interface options panel.
Zerotorescue@0 1867 -- @return The reference to the frame registered into the Interface Options.
Zerotorescue@0 1868 function AceConfigDialog:AddToBlizOptions(appName, name, parent, ...)
Zerotorescue@0 1869 local BlizOptions = AceConfigDialog.BlizOptions
Zerotorescue@0 1870
Zerotorescue@0 1871 local key = appName
Zerotorescue@0 1872 for n = 1, select("#", ...) do
Zerotorescue@0 1873 key = key.."\001"..select(n, ...)
Zerotorescue@0 1874 end
Zerotorescue@0 1875
Zerotorescue@0 1876 if not BlizOptions[appName] then
Zerotorescue@0 1877 BlizOptions[appName] = {}
Zerotorescue@0 1878 end
Zerotorescue@0 1879
Zerotorescue@0 1880 if not BlizOptions[appName][key] then
Zerotorescue@0 1881 local group = gui:Create("BlizOptionsGroup")
Zerotorescue@0 1882 BlizOptions[appName][key] = group
Zerotorescue@0 1883 group:SetName(name or appName, parent)
Zerotorescue@0 1884
Zerotorescue@0 1885 group:SetTitle(name or appName)
Zerotorescue@0 1886 group:SetUserData("appName", appName)
Zerotorescue@0 1887 if select("#", ...) > 0 then
Zerotorescue@0 1888 local path = {}
Zerotorescue@0 1889 for n = 1, select("#",...) do
Zerotorescue@0 1890 tinsert(path, (select(n, ...)))
Zerotorescue@0 1891 end
Zerotorescue@0 1892 group:SetUserData("path", path)
Zerotorescue@0 1893 end
Zerotorescue@0 1894 group:SetCallback("OnShow", FeedToBlizPanel)
Zerotorescue@0 1895 group:SetCallback("OnHide", ClearBlizPanel)
Zerotorescue@0 1896 InterfaceOptions_AddCategory(group.frame)
Zerotorescue@0 1897 return group.frame
Zerotorescue@0 1898 else
Zerotorescue@0 1899 error(("%s has already been added to the Blizzard Options Window with the given path"):format(appName), 2)
Zerotorescue@0 1900 end
Zerotorescue@0 1901 end