annotate Editor.lua @ 185:2e7a322e0195

move ConfigUI module to Editor non-module, make it more self-contained
author Flick <flickerstreak@gmail.com>
date Fri, 22 Oct 2010 23:48:02 +0000
parents modules/ConfigUI.lua@1ee86bbb05a0
children d58055179c16
rev   line source
flickerstreak@175 1 local addonName, addonTable = ...
flickerstreak@175 2 local ReAction = addonTable.ReAction
flickerstreak@109 3 local L = ReAction.L
flickerstreak@109 4 local _G = _G
flickerstreak@185 5 local wipe = wipe
flickerstreak@185 6
flickerstreak@109 7 local AceConfigReg = LibStub("AceConfigRegistry-3.0")
flickerstreak@109 8 local AceConfigDialog = LibStub("AceConfigDialog-3.0")
flickerstreak@109 9
flickerstreak@109 10
flickerstreak@185 11 local pointTable = {
flickerstreak@185 12 CENTER = L["Center"],
flickerstreak@185 13 LEFT = L["Left"],
flickerstreak@185 14 RIGHT = L["Right"],
flickerstreak@185 15 TOP = L["Top"],
flickerstreak@185 16 BOTTOM = L["Bottom"],
flickerstreak@185 17 TOPLEFT = L["Top Left"],
flickerstreak@185 18 TOPRIGHT = L["Top Right"],
flickerstreak@185 19 BOTTOMLEFT = L["Bottom Left"],
flickerstreak@185 20 BOTTOMRIGHT = L["Bottom Right"],
flickerstreak@185 21 }
flickerstreak@109 22
flickerstreak@185 23 local Editor = { }
flickerstreak@109 24
flickerstreak@185 25 function Editor:New()
flickerstreak@185 26 -- create new self
flickerstreak@185 27 self = setmetatable( { }, { __index = self } )
flickerstreak@109 28
flickerstreak@185 29 self.barOptMap = setmetatable({},{__mode="v"})
flickerstreak@185 30 self.tmp = { }
flickerstreak@185 31 self.configID = "ReAction-Editor"
flickerstreak@109 32
flickerstreak@185 33 self.gui = LibStub("AceGUI-3.0"):Create("Frame")
flickerstreak@185 34
flickerstreak@185 35 local frame = self.gui.frame
flickerstreak@109 36 frame:SetClampedToScreen(true)
flickerstreak@109 37 frame:Hide()
flickerstreak@185 38
flickerstreak@185 39 frame:SetScript("OnHide",
flickerstreak@185 40 function(...)
flickerstreak@109 41 ReAction:SetConfigMode(false)
flickerstreak@185 42 end)
flickerstreak@109 43
flickerstreak@185 44 self.options = {
flickerstreak@109 45 type = "group",
flickerstreak@185 46 name = L["Select Bar:"],
flickerstreak@185 47 desc = "foo foo foo",
flickerstreak@185 48 handler = self,
flickerstreak@185 49 childGroups = "select",
flickerstreak@109 50 args = {
flickerstreak@109 51 launchConfig = {
flickerstreak@109 52 type = "execute",
flickerstreak@109 53 name = L["Global Config"],
flickerstreak@109 54 desc = L["Opens ReAction global configuration settings panel"],
flickerstreak@109 55 func = function()
flickerstreak@185 56 if ReAction.db.profile.editorCloseOnLaunch then
flickerstreak@185 57 self:Close()
flickerstreak@185 58 end
flickerstreak@182 59 ReAction:ShowOptions()
flickerstreak@109 60 end,
flickerstreak@185 61 order = 1
flickerstreak@109 62 },
flickerstreak@109 63 closeThis = {
flickerstreak@109 64 type = "toggle",
flickerstreak@185 65 name = L["Close Editor"],
flickerstreak@109 66 desc = L["Close the Bar Editor when opening the ReAction global Interface Options"],
flickerstreak@185 67 get = function() return ReAction.db.profile.editorCloseOnLaunch end,
flickerstreak@185 68 set = function(info, val) ReAction.db.profile.editorCloseOnLaunch = val end,
flickerstreak@185 69 order = 2,
flickerstreak@185 70 },
flickerstreak@185 71 hdr = {
flickerstreak@185 72 type = "header",
flickerstreak@185 73 name = "",
flickerstreak@109 74 order = 3,
flickerstreak@109 75 },
flickerstreak@185 76 desc = {
flickerstreak@185 77 type = "description",
flickerstreak@185 78 name = L["Use the mouse to arrange and resize the bars on screen. Tooltips on bars indicate additional functionality."],
flickerstreak@185 79 width = "double",
flickerstreak@185 80 order = 4,
flickerstreak@185 81 },
flickerstreak@185 82 _new = {
flickerstreak@109 83 type = "group",
flickerstreak@109 84 name = L["New Bar..."],
flickerstreak@185 85 order = 5,
flickerstreak@109 86 args = {
flickerstreak@109 87 desc = {
flickerstreak@109 88 type = "description",
flickerstreak@109 89 name = L["Choose a name, type, and initial grid for your new action bar:"],
flickerstreak@109 90 order = 1,
flickerstreak@109 91 },
flickerstreak@109 92 name = {
flickerstreak@109 93 type = "input",
flickerstreak@109 94 name = L["Bar Name"],
flickerstreak@109 95 desc = L["Enter a name for your new action bar"],
flickerstreak@185 96 get = function() return self.tmp.barName or "" end,
flickerstreak@185 97 set = function(info, val) self.tmp.barName = val end,
flickerstreak@109 98 order = 2,
flickerstreak@109 99 },
flickerstreak@109 100 type = {
flickerstreak@109 101 type = "select",
flickerstreak@109 102 name = L["Button Type"],
flickerstreak@185 103 get = function() return self.tmp.barType or ReAction:GetDefaultBarType() or "" end,
flickerstreak@109 104 set = function(info, val)
flickerstreak@109 105 local c = ReAction:GetBarTypeConfig(val)
flickerstreak@185 106 self.tmp.barType = val
flickerstreak@185 107 self.tmp.barSize = c.defaultButtonSize or self.tmp.barSize
flickerstreak@185 108 self.tmp.barRows = c.defaultBarRows or self.tmp.barRows
flickerstreak@185 109 self.tmp.barCols = c.defaultBarCols or self.tmp.barCols
flickerstreak@185 110 self.tmp.barSpacing = c.defaultBarSpacing or self.tmp.barSpacing
flickerstreak@109 111 end,
flickerstreak@109 112 values = "GetBarTypes",
flickerstreak@109 113 order = 3,
flickerstreak@109 114 },
flickerstreak@185 115 go = {
flickerstreak@185 116 type = "execute",
flickerstreak@185 117 name = L["Create Bar"],
flickerstreak@185 118 func = "CreateBar",
flickerstreak@185 119 order = 4,
flickerstreak@185 120 },
flickerstreak@109 121 grid = {
flickerstreak@109 122 type = "group",
flickerstreak@109 123 name = L["Button Grid"],
flickerstreak@109 124 inline = true,
flickerstreak@185 125 order = 5,
flickerstreak@109 126 args = {
flickerstreak@109 127 rows = {
flickerstreak@109 128 type = "range",
flickerstreak@109 129 name = L["Rows"],
flickerstreak@185 130 get = function() return self.tmp.barRows or 1 end,
flickerstreak@185 131 set = function(info, val) self.tmp.barRows = val end,
flickerstreak@185 132 width = "full",
flickerstreak@109 133 min = 1,
flickerstreak@109 134 max = 32,
flickerstreak@109 135 step = 1,
flickerstreak@109 136 order = 2,
flickerstreak@109 137 },
flickerstreak@109 138 cols = {
flickerstreak@109 139 type = "range",
flickerstreak@109 140 name = L["Columns"],
flickerstreak@185 141 get = function() return self.tmp.barCols or 12 end,
flickerstreak@185 142 set = function(info, val) self.tmp.barCols = val end,
flickerstreak@185 143 width = "full",
flickerstreak@109 144 min = 1,
flickerstreak@109 145 max = 32,
flickerstreak@109 146 step = 1,
flickerstreak@109 147 order = 3,
flickerstreak@109 148 },
flickerstreak@109 149 sz = {
flickerstreak@109 150 type = "range",
flickerstreak@109 151 name = L["Size"],
flickerstreak@185 152 get = function() return self.tmp.barSize or 36 end,
flickerstreak@185 153 set = function(info, val) self.tmp.barSize = val end,
flickerstreak@185 154 width = "full",
flickerstreak@109 155 min = 10,
flickerstreak@109 156 max = 72,
flickerstreak@109 157 step = 1,
flickerstreak@109 158 order = 4,
flickerstreak@109 159 },
flickerstreak@109 160 spacing = {
flickerstreak@109 161 type = "range",
flickerstreak@109 162 name = L["Spacing"],
flickerstreak@185 163 get = function() return self.tmp.barSpacing or 3 end,
flickerstreak@185 164 set = function(info, val) self.tmp.barSpacing = val end,
flickerstreak@185 165 width = "full",
flickerstreak@109 166 min = 0,
flickerstreak@109 167 max = 24,
flickerstreak@109 168 step = 1,
flickerstreak@109 169 order = 5,
flickerstreak@109 170 }
flickerstreak@109 171 },
flickerstreak@109 172 },
flickerstreak@109 173 }
flickerstreak@109 174 }
flickerstreak@185 175 },
flickerstreak@109 176 }
flickerstreak@109 177
flickerstreak@185 178 self.title = ("%s - %s"):format(L["ReAction"],L["Bar Editor"])
flickerstreak@185 179 self.gui:SetTitle(self.title)
flickerstreak@185 180
flickerstreak@185 181 self.gui:SetCallback("OnClose",
flickerstreak@185 182 function()
flickerstreak@185 183 ReAction:SetConfigMode(false)
flickerstreak@185 184 end )
flickerstreak@185 185
flickerstreak@185 186 AceConfigReg:RegisterOptionsTable(self.configID, self.options)
flickerstreak@185 187 AceConfigDialog:SetDefaultSize(self.configID, 700, 540)
flickerstreak@185 188
flickerstreak@185 189 ReAction.RegisterCallback(self,"OnCreateBar")
flickerstreak@185 190 ReAction.RegisterCallback(self,"OnDestroyBar")
flickerstreak@185 191 ReAction.RegisterCallback(self,"OnEraseBar")
flickerstreak@185 192 ReAction.RegisterCallback(self,"OnRenameBar")
flickerstreak@185 193
flickerstreak@185 194 for name, bar in ReAction:IterateBars() do
flickerstreak@185 195 self:CreateBarTree(bar)
flickerstreak@109 196 end
flickerstreak@109 197
flickerstreak@185 198 return self
flickerstreak@109 199 end
flickerstreak@109 200
flickerstreak@109 201
flickerstreak@185 202 function Editor:Open(bar, ...)
flickerstreak@185 203 if bar then
flickerstreak@185 204 AceConfigDialog:SelectGroup(self.configID, self.barOptMap[bar:GetName()], ...)
flickerstreak@185 205 end
flickerstreak@185 206 AceConfigDialog:Open(self.configID,self.gui)
flickerstreak@185 207 self.gui:SetTitle(self.title)
flickerstreak@185 208 end
flickerstreak@185 209
flickerstreak@185 210 function Editor:Close()
flickerstreak@185 211 if self.gui then
flickerstreak@185 212 print("closing...")
flickerstreak@185 213 self.gui:ReleaseChildren()
flickerstreak@185 214 self.gui:Hide()
flickerstreak@109 215 end
flickerstreak@109 216 end
flickerstreak@109 217
flickerstreak@185 218 function Editor:Refresh()
flickerstreak@185 219 AceConfigReg:NotifyChange(self.configID)
flickerstreak@185 220 end
flickerstreak@185 221
flickerstreak@185 222 function Editor:CreateBarTree(bar)
flickerstreak@185 223 local name = bar:GetName()
flickerstreak@185 224 -- AceConfig doesn't allow spaces, etc, in arg key names, and they must be
flickerstreak@185 225 -- unique strings. So generate a unique key (it can be whatever) for the bar
flickerstreak@185 226 local args = self.options.args
flickerstreak@185 227 local key
flickerstreak@185 228 local i = 1
flickerstreak@185 229 repeat
flickerstreak@185 230 key = ("bar%s"):format(i)
flickerstreak@185 231 i = i+1
flickerstreak@185 232 until args[key] == nil
flickerstreak@185 233 self.barOptMap[name] = key
flickerstreak@185 234 args[key] = {
flickerstreak@185 235 type = "group",
flickerstreak@185 236 name = name,
flickerstreak@185 237 childGroups = "tab",
flickerstreak@185 238 order = i+100,
flickerstreak@185 239 args = {
flickerstreak@185 240 general = {
flickerstreak@185 241 type = "group",
flickerstreak@185 242 name = L["General"],
flickerstreak@185 243 order = 1,
flickerstreak@185 244 args = {
flickerstreak@185 245 name = {
flickerstreak@185 246 type = "input",
flickerstreak@185 247 name = L["Rename Bar"],
flickerstreak@185 248 get = function() return bar:GetName() end,
flickerstreak@185 249 set = function(info, value) return ReAction:RenameBar(bar, value) end,
flickerstreak@185 250 order = 1,
flickerstreak@185 251 },
flickerstreak@185 252 delete = {
flickerstreak@185 253 type = "execute",
flickerstreak@185 254 name = L["Delete Bar"],
flickerstreak@185 255 desc = function() return bar:GetName() end,
flickerstreak@185 256 confirm = true,
flickerstreak@185 257 func = function() ReAction:EraseBar(bar) end,
flickerstreak@185 258 order = 2
flickerstreak@185 259 },
flickerstreak@185 260 anchor = {
flickerstreak@185 261 type = "group",
flickerstreak@185 262 name = L["Anchor"],
flickerstreak@185 263 inline = true,
flickerstreak@185 264 args = {
flickerstreak@185 265 frame = {
flickerstreak@185 266 type = "input",
flickerstreak@185 267 name = L["Frame"],
flickerstreak@185 268 desc = L["The frame that the bar is anchored to"],
flickerstreak@185 269 get = function() local _, f = bar:GetAnchor(); return f end,
flickerstreak@185 270 set = function(info, val) bar:SetAnchor(nil,val) end,
flickerstreak@185 271 validate = function(info, name)
flickerstreak@185 272 if name then
flickerstreak@185 273 local f = ReAction:GetBar(name)
flickerstreak@185 274 if f then
flickerstreak@185 275 return true
flickerstreak@185 276 else
flickerstreak@185 277 f = _G[name]
flickerstreak@185 278 if f and type(f) == "table" and f.IsObjectType and f:IsObjectType("Frame") then
flickerstreak@185 279 local _, explicit = f:IsProtected()
flickerstreak@185 280 return explicit
flickerstreak@185 281 end
flickerstreak@185 282 end
flickerstreak@185 283 end
flickerstreak@185 284 return false
flickerstreak@185 285 end,
flickerstreak@185 286 width = "double",
flickerstreak@185 287 order = 1
flickerstreak@185 288 },
flickerstreak@185 289 point = {
flickerstreak@185 290 type = "select",
flickerstreak@185 291 name = L["Point"],
flickerstreak@185 292 desc = L["Anchor point on the bar frame"],
flickerstreak@185 293 style = "dropdown",
flickerstreak@185 294 get = function() return bar:GetAnchor() end,
flickerstreak@185 295 set = function(info, val) bar:SetAnchor(val) end,
flickerstreak@185 296 values = pointTable,
flickerstreak@185 297 order = 2,
flickerstreak@185 298 },
flickerstreak@185 299 relativePoint = {
flickerstreak@185 300 type = "select",
flickerstreak@185 301 name = L["Relative Point"],
flickerstreak@185 302 desc = L["Anchor point on the target frame"],
flickerstreak@185 303 style = "dropdown",
flickerstreak@185 304 get = function() local p,f,r = bar:GetAnchor(); return r end,
flickerstreak@185 305 set = function(info, val) bar:SetAnchor(nil,nil,val) end,
flickerstreak@185 306 values = pointTable,
flickerstreak@185 307 order = 3,
flickerstreak@185 308 },
flickerstreak@185 309 x = {
flickerstreak@185 310 type = "input",
flickerstreak@185 311 pattern = "\-?%d+",
flickerstreak@185 312 name = L["X offset"],
flickerstreak@185 313 get = function() local p,f,r,x = bar:GetAnchor(); return ("%d"):format(x) end,
flickerstreak@185 314 set = function(info,val) bar:SetAnchor(nil,nil,nil,val) end,
flickerstreak@185 315 order = 4
flickerstreak@185 316 },
flickerstreak@185 317 y = {
flickerstreak@185 318 type = "input",
flickerstreak@185 319 pattern = "\-?%d+",
flickerstreak@185 320 name = L["Y offset"],
flickerstreak@185 321 get = function() local p,f,r,x,y = bar:GetAnchor(); return ("%d"):format(y) end,
flickerstreak@185 322 set = function(info,val) bar:SetAnchor(nil,nil,nil,nil,val) end,
flickerstreak@185 323 order = 5
flickerstreak@185 324 },
flickerstreak@185 325 },
flickerstreak@185 326 order = 3
flickerstreak@185 327 },
flickerstreak@185 328 alpha = {
flickerstreak@185 329 type = "range",
flickerstreak@185 330 name = L["Transparency"],
flickerstreak@185 331 get = function() return bar:GetAlpha() end,
flickerstreak@185 332 set = function(info, val) bar:SetAlpha(val) end,
flickerstreak@185 333 min = 0,
flickerstreak@185 334 max = 1,
flickerstreak@185 335 isPercent = true,
flickerstreak@185 336 step = 0.01,
flickerstreak@185 337 bigStep = 0.05,
flickerstreak@185 338 order = 4,
flickerstreak@185 339 },
flickerstreak@185 340 },
flickerstreak@185 341 },
flickerstreak@185 342 }
flickerstreak@185 343 }
flickerstreak@185 344 self:RefreshBarOptions()
flickerstreak@185 345 end
flickerstreak@185 346
flickerstreak@185 347 function Editor:RefreshBarOptions()
flickerstreak@185 348 for name, key in pairs(self.barOptMap) do
flickerstreak@185 349 local bar = ReAction:GetBar(name)
flickerstreak@185 350 if bar and key and self.options.args[key] then
flickerstreak@185 351 self.options.args[key].plugins = self:GenerateBarOptionsTable(bar)
flickerstreak@185 352 end
flickerstreak@185 353 end
flickerstreak@185 354 AceConfigReg:NotifyChange(self.configID)
flickerstreak@185 355 end
flickerstreak@185 356
flickerstreak@185 357 function Editor:OnCreateBar(evt, bar)
flickerstreak@185 358 if not self.tmp.creating then
flickerstreak@185 359 -- a bit of hack to work around OnCreateBar event handler ordering
flickerstreak@185 360 self:CreateBarTree(bar)
flickerstreak@185 361 end
flickerstreak@185 362 end
flickerstreak@185 363
flickerstreak@185 364 function Editor:OnDestroyBar(evt, bar, name)
flickerstreak@185 365 local key = self.barOptMap[name]
flickerstreak@185 366 if key then
flickerstreak@185 367 self.options.args[key] = nil
flickerstreak@185 368 end
flickerstreak@185 369 self:Refresh()
flickerstreak@185 370 end
flickerstreak@185 371
flickerstreak@185 372 function Editor:OnEraseBar(evt, name)
flickerstreak@185 373 local key = self.barOptMap[name]
flickerstreak@185 374 self.barOptMap[name] = nil
flickerstreak@185 375 if key then
flickerstreak@185 376 self.options.args[key] = nil
flickerstreak@185 377 self:Refresh()
flickerstreak@185 378 end
flickerstreak@185 379 end
flickerstreak@185 380
flickerstreak@185 381 function Editor:OnRenameBar(evt, bar, oldname, newname)
flickerstreak@185 382 local key = self.barOptMap[oldname]
flickerstreak@185 383 self.barOptMap[oldname], self.barOptMap[newname] = nil, key
flickerstreak@185 384 if key then
flickerstreak@185 385 self.options.args[key].name = newname
flickerstreak@185 386 self:Refresh()
flickerstreak@185 387 end
flickerstreak@185 388 end
flickerstreak@185 389
flickerstreak@185 390 local _scratch = { }
flickerstreak@185 391 function Editor:GetBarTypes()
flickerstreak@185 392 wipe(_scratch)
flickerstreak@185 393 return ReAction:GetBarTypeOptions(_scratch)
flickerstreak@185 394 end
flickerstreak@185 395
flickerstreak@185 396 function Editor:CreateBar()
flickerstreak@185 397 if self.tmp.barName and self.tmp.barName ~= "" then
flickerstreak@185 398 self.tmp.creating = true
flickerstreak@185 399 local bar = ReAction:CreateBar(self.tmp.barName, self.tmp.barType or ReAction:GetDefaultBarType(), self.tmp.barRows, self.tmp.barCols, self.tmp.barSize, self.tmp.barSpacing)
flickerstreak@185 400 if bar then
flickerstreak@185 401 self:CreateBarTree(bar)
flickerstreak@185 402 AceConfigDialog:SelectGroup(self.configID, self.barOptMap[self.tmp.barName])
flickerstreak@185 403 self.tmp.barName = nil
flickerstreak@185 404 end
flickerstreak@185 405 self.tmp.creating = false
flickerstreak@185 406 end
flickerstreak@185 407 end
flickerstreak@185 408
flickerstreak@185 409 function Editor:GenerateBarOptionsTable( bar )
flickerstreak@185 410 local opts = { }
flickerstreak@185 411 if not ReAction.barOptionGenerators then
flickerstreak@185 412 return
flickerstreak@185 413 end
flickerstreak@185 414
flickerstreak@185 415 for module, func in pairs(ReAction.barOptionGenerators) do
flickerstreak@185 416 local success, r
flickerstreak@185 417 if type(func) == "string" then
flickerstreak@185 418 success, r = pcall(module[func], module, bar)
flickerstreak@185 419 else
flickerstreak@185 420 success, r = pcall(func, bar)
flickerstreak@185 421 end
flickerstreak@185 422 if success then
flickerstreak@185 423 if r then
flickerstreak@185 424 opts[module:GetName()] = { [module:GetName()] = r }
flickerstreak@185 425 end
flickerstreak@185 426 else
flickerstreak@185 427 geterrorhandler()(r)
flickerstreak@185 428 end
flickerstreak@185 429 end
flickerstreak@185 430 return opts
flickerstreak@185 431 end
flickerstreak@185 432
flickerstreak@185 433
flickerstreak@185 434
flickerstreak@185 435 ---- Export to ReAction ----
flickerstreak@185 436 function ReAction:ShowEditor(bar, ...)
flickerstreak@185 437 if InCombatLockdown() then
flickerstreak@185 438 self:UserError(L["ReAction config mode disabled during combat."])
flickerstreak@185 439 else
flickerstreak@185 440 self.editor = self.editor or Editor:New()
flickerstreak@185 441 self.editor:Open(bar, ...)
flickerstreak@185 442 self:SetConfigMode(true)
flickerstreak@185 443 end
flickerstreak@185 444 end
flickerstreak@185 445
flickerstreak@185 446 function ReAction:CloseEditor()
flickerstreak@185 447 if self.editor then
flickerstreak@185 448 self.editor:Close()
flickerstreak@185 449 end
flickerstreak@185 450 end
flickerstreak@185 451
flickerstreak@185 452 function ReAction:RefreshEditor()
flickerstreak@185 453 if self.editor then
flickerstreak@185 454 self.editor:RefreshBarOptions()
flickerstreak@185 455 end
flickerstreak@185 456 end
flickerstreak@185 457
flickerstreak@185 458 function ReAction:RegisterBarOptionGenerator( module, func )
flickerstreak@185 459 if not module or type(module) ~= "table" then -- doesn't need to be a proper module, strictly
flickerstreak@185 460 error("ReAction:RegisterBarOptionGenerator() : Invalid module")
flickerstreak@185 461 end
flickerstreak@185 462 if type(func) == "string" then
flickerstreak@185 463 if not module[func] then
flickerstreak@185 464 error(("ReAction:RegisterBarOptionGenerator() : Invalid method '%s'"):format(func))
flickerstreak@185 465 end
flickerstreak@185 466 elseif func and type(func) ~= "function" then
flickerstreak@185 467 error("ReAction:RegisterBarOptionGenerator() : Invalid function")
flickerstreak@185 468 end
flickerstreak@185 469 self.barOptionGenerators = self.barOptionGenerators or { }
flickerstreak@185 470 self.barOptionGenerators[module] = func
flickerstreak@185 471
flickerstreak@185 472 if self.editor then
flickerstreak@185 473 self.editor:RefreshBarOptions()
flickerstreak@185 474 end
flickerstreak@185 475 end
flickerstreak@185 476