annotate Libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua @ 0:98c6f55e6619

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