annotate Editor.lua @ 216:376c424900f0

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