annotate Editor.lua @ 195:85213d045acb

Fix editor panel title
author Flick <flickerstreak@gmail.com>
date Mon, 15 Nov 2010 11:01:42 -0800
parents 55af1ebbec65
children 376c424900f0
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,"OnEraseBar")
flickerstreak@185 177 ReAction.RegisterCallback(self,"OnRenameBar")
flickerstreak@185 178
flickerstreak@185 179 for name, bar in ReAction:IterateBars() do
flickerstreak@185 180 self:CreateBarTree(bar)
flickerstreak@109 181 end
flickerstreak@109 182
flickerstreak@185 183 return self
flickerstreak@109 184 end
flickerstreak@109 185
flickerstreak@109 186
flickerstreak@185 187 function Editor:Open(bar, ...)
flickerstreak@185 188 if bar then
flickerstreak@185 189 AceConfigDialog:SelectGroup(self.configID, self.barOptMap[bar:GetName()], ...)
flickerstreak@185 190 end
flickerstreak@185 191 AceConfigDialog:Open(self.configID,self.gui)
flickerstreak@185 192 self.gui:SetTitle(self.title)
flickerstreak@185 193 end
flickerstreak@185 194
flickerstreak@185 195 function Editor:Close()
flickerstreak@185 196 if self.gui then
flickerstreak@185 197 self.gui:ReleaseChildren()
flickerstreak@185 198 self.gui:Hide()
flickerstreak@109 199 end
flickerstreak@109 200 end
flickerstreak@109 201
flickerstreak@185 202 function Editor:Refresh()
flickerstreak@185 203 AceConfigReg:NotifyChange(self.configID)
flickerstreak@185 204 end
flickerstreak@185 205
flickerstreak@185 206 function Editor:CreateBarTree(bar)
flickerstreak@185 207 local name = bar:GetName()
flickerstreak@185 208 -- AceConfig doesn't allow spaces, etc, in arg key names, and they must be
flickerstreak@185 209 -- unique strings. So generate a unique key (it can be whatever) for the bar
flickerstreak@185 210 local args = self.options.args
flickerstreak@185 211 local key
flickerstreak@185 212 local i = 1
flickerstreak@185 213 repeat
flickerstreak@185 214 key = ("bar%s"):format(i)
flickerstreak@185 215 i = i+1
flickerstreak@185 216 until args[key] == nil
flickerstreak@185 217 self.barOptMap[name] = key
flickerstreak@185 218 args[key] = {
flickerstreak@185 219 type = "group",
flickerstreak@185 220 name = name,
flickerstreak@185 221 childGroups = "tab",
flickerstreak@185 222 order = i+100,
flickerstreak@185 223 args = {
flickerstreak@185 224 general = {
flickerstreak@185 225 type = "group",
flickerstreak@185 226 name = L["General"],
flickerstreak@185 227 order = 1,
flickerstreak@185 228 args = {
flickerstreak@185 229 name = {
flickerstreak@185 230 type = "input",
flickerstreak@185 231 name = L["Rename Bar"],
flickerstreak@185 232 get = function() return bar:GetName() end,
flickerstreak@185 233 set = function(info, value) return ReAction:RenameBar(bar, value) end,
flickerstreak@185 234 order = 1,
flickerstreak@185 235 },
flickerstreak@185 236 delete = {
flickerstreak@185 237 type = "execute",
flickerstreak@185 238 name = L["Delete Bar"],
flickerstreak@185 239 desc = function() return bar:GetName() end,
flickerstreak@185 240 confirm = true,
flickerstreak@185 241 func = function() ReAction:EraseBar(bar) end,
flickerstreak@185 242 order = 2
flickerstreak@185 243 },
flickerstreak@185 244 anchor = {
flickerstreak@185 245 type = "group",
flickerstreak@185 246 name = L["Anchor"],
flickerstreak@185 247 inline = true,
flickerstreak@185 248 args = {
flickerstreak@185 249 frame = {
flickerstreak@185 250 type = "input",
flickerstreak@185 251 name = L["Frame"],
flickerstreak@185 252 desc = L["The frame that the bar is anchored to"],
flickerstreak@185 253 get = function() local _, f = bar:GetAnchor(); return f end,
flickerstreak@185 254 set = function(info, val) bar:SetAnchor(nil,val) end,
flickerstreak@185 255 validate = function(info, name)
flickerstreak@185 256 if name then
flickerstreak@185 257 local f = ReAction:GetBar(name)
flickerstreak@185 258 if f then
flickerstreak@185 259 return true
flickerstreak@185 260 else
flickerstreak@185 261 f = _G[name]
flickerstreak@185 262 if f and type(f) == "table" and f.IsObjectType and f:IsObjectType("Frame") then
flickerstreak@185 263 local _, explicit = f:IsProtected()
flickerstreak@185 264 return explicit
flickerstreak@185 265 end
flickerstreak@185 266 end
flickerstreak@185 267 end
flickerstreak@185 268 return false
flickerstreak@185 269 end,
flickerstreak@185 270 width = "double",
flickerstreak@185 271 order = 1
flickerstreak@185 272 },
flickerstreak@185 273 point = {
flickerstreak@185 274 type = "select",
flickerstreak@185 275 name = L["Point"],
flickerstreak@185 276 desc = L["Anchor point on the bar frame"],
flickerstreak@185 277 style = "dropdown",
flickerstreak@185 278 get = function() return bar:GetAnchor() end,
flickerstreak@185 279 set = function(info, val) bar:SetAnchor(val) end,
flickerstreak@185 280 values = pointTable,
flickerstreak@185 281 order = 2,
flickerstreak@185 282 },
flickerstreak@185 283 relativePoint = {
flickerstreak@185 284 type = "select",
flickerstreak@185 285 name = L["Relative Point"],
flickerstreak@185 286 desc = L["Anchor point on the target frame"],
flickerstreak@185 287 style = "dropdown",
flickerstreak@185 288 get = function() local p,f,r = bar:GetAnchor(); return r end,
flickerstreak@185 289 set = function(info, val) bar:SetAnchor(nil,nil,val) end,
flickerstreak@185 290 values = pointTable,
flickerstreak@185 291 order = 3,
flickerstreak@185 292 },
flickerstreak@185 293 x = {
flickerstreak@185 294 type = "input",
flickerstreak@185 295 pattern = "\-?%d+",
flickerstreak@185 296 name = L["X offset"],
flickerstreak@185 297 get = function() local p,f,r,x = bar:GetAnchor(); return ("%d"):format(x) end,
flickerstreak@185 298 set = function(info,val) bar:SetAnchor(nil,nil,nil,val) end,
flickerstreak@185 299 order = 4
flickerstreak@185 300 },
flickerstreak@185 301 y = {
flickerstreak@185 302 type = "input",
flickerstreak@185 303 pattern = "\-?%d+",
flickerstreak@185 304 name = L["Y offset"],
flickerstreak@185 305 get = function() local p,f,r,x,y = bar:GetAnchor(); return ("%d"):format(y) end,
flickerstreak@185 306 set = function(info,val) bar:SetAnchor(nil,nil,nil,nil,val) end,
flickerstreak@185 307 order = 5
flickerstreak@185 308 },
flickerstreak@185 309 },
flickerstreak@185 310 order = 3
flickerstreak@185 311 },
flickerstreak@185 312 alpha = {
flickerstreak@185 313 type = "range",
flickerstreak@185 314 name = L["Transparency"],
flickerstreak@185 315 get = function() return bar:GetAlpha() end,
flickerstreak@185 316 set = function(info, val) bar:SetAlpha(val) end,
flickerstreak@185 317 min = 0,
flickerstreak@185 318 max = 1,
flickerstreak@185 319 isPercent = true,
flickerstreak@185 320 step = 0.01,
flickerstreak@185 321 bigStep = 0.05,
flickerstreak@185 322 order = 4,
flickerstreak@185 323 },
flickerstreak@185 324 },
flickerstreak@185 325 },
flickerstreak@185 326 }
flickerstreak@185 327 }
flickerstreak@185 328 self:RefreshBarOptions()
flickerstreak@185 329 end
flickerstreak@185 330
flickerstreak@185 331 function Editor:RefreshBarOptions()
flickerstreak@185 332 for name, key in pairs(self.barOptMap) do
flickerstreak@185 333 local bar = ReAction:GetBar(name)
flickerstreak@185 334 if bar and key and self.options.args[key] then
flickerstreak@185 335 self.options.args[key].plugins = self:GenerateBarOptionsTable(bar)
flickerstreak@185 336 end
flickerstreak@185 337 end
flickerstreak@185 338 AceConfigReg:NotifyChange(self.configID)
flickerstreak@185 339 end
flickerstreak@185 340
flickerstreak@185 341 function Editor:OnCreateBar(evt, bar)
flickerstreak@185 342 if not self.tmp.creating then
flickerstreak@185 343 -- a bit of hack to work around OnCreateBar event handler ordering
flickerstreak@185 344 self:CreateBarTree(bar)
flickerstreak@185 345 end
flickerstreak@185 346 end
flickerstreak@185 347
flickerstreak@185 348 function Editor:OnDestroyBar(evt, bar, name)
flickerstreak@185 349 local key = self.barOptMap[name]
flickerstreak@185 350 if key then
flickerstreak@185 351 self.options.args[key] = nil
flickerstreak@185 352 end
flickerstreak@185 353 self:Refresh()
flickerstreak@185 354 end
flickerstreak@185 355
flickerstreak@185 356 function Editor:OnEraseBar(evt, name)
flickerstreak@185 357 local key = self.barOptMap[name]
flickerstreak@185 358 self.barOptMap[name] = nil
flickerstreak@185 359 if key then
flickerstreak@185 360 self.options.args[key] = nil
flickerstreak@185 361 self:Refresh()
flickerstreak@185 362 end
flickerstreak@185 363 end
flickerstreak@185 364
flickerstreak@185 365 function Editor:OnRenameBar(evt, bar, oldname, newname)
flickerstreak@185 366 local key = self.barOptMap[oldname]
flickerstreak@185 367 self.barOptMap[oldname], self.barOptMap[newname] = nil, key
flickerstreak@185 368 if key then
flickerstreak@185 369 self.options.args[key].name = newname
flickerstreak@185 370 self:Refresh()
flickerstreak@185 371 end
flickerstreak@185 372 end
flickerstreak@185 373
flickerstreak@185 374 local _scratch = { }
flickerstreak@185 375 function Editor:GetBarTypes()
flickerstreak@185 376 wipe(_scratch)
flickerstreak@185 377 return ReAction:GetBarTypeOptions(_scratch)
flickerstreak@185 378 end
flickerstreak@185 379
flickerstreak@185 380 function Editor:CreateBar()
flickerstreak@185 381 if self.tmp.barName and self.tmp.barName ~= "" then
flickerstreak@185 382 self.tmp.creating = true
flickerstreak@185 383 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 384 if bar then
flickerstreak@185 385 self:CreateBarTree(bar)
flickerstreak@185 386 AceConfigDialog:SelectGroup(self.configID, self.barOptMap[self.tmp.barName])
flickerstreak@185 387 self.tmp.barName = nil
flickerstreak@185 388 end
flickerstreak@185 389 self.tmp.creating = false
flickerstreak@185 390 end
flickerstreak@185 391 end
flickerstreak@185 392
flickerstreak@185 393 function Editor:GenerateBarOptionsTable( bar )
flickerstreak@185 394 local opts = { }
flickerstreak@185 395 if not ReAction.barOptionGenerators then
flickerstreak@185 396 return
flickerstreak@185 397 end
flickerstreak@185 398
flickerstreak@185 399 for module, func in pairs(ReAction.barOptionGenerators) do
flickerstreak@185 400 local success, r
flickerstreak@185 401 if type(func) == "string" then
flickerstreak@185 402 success, r = pcall(module[func], module, bar)
flickerstreak@185 403 else
flickerstreak@185 404 success, r = pcall(func, bar)
flickerstreak@185 405 end
flickerstreak@185 406 if success then
flickerstreak@185 407 if r then
flickerstreak@185 408 opts[module:GetName()] = { [module:GetName()] = r }
flickerstreak@185 409 end
flickerstreak@185 410 else
flickerstreak@185 411 geterrorhandler()(r)
flickerstreak@185 412 end
flickerstreak@185 413 end
flickerstreak@185 414 return opts
flickerstreak@185 415 end
flickerstreak@185 416
flickerstreak@185 417
flickerstreak@185 418
flickerstreak@185 419 ---- Export to ReAction ----
flickerstreak@185 420 function ReAction:ShowEditor(bar, ...)
flickerstreak@185 421 if InCombatLockdown() then
flickerstreak@185 422 self:UserError(L["ReAction config mode disabled during combat."])
flickerstreak@185 423 else
flickerstreak@185 424 self.editor = self.editor or Editor:New()
flickerstreak@185 425 self.editor:Open(bar, ...)
flickerstreak@185 426 self:SetConfigMode(true)
flickerstreak@185 427 end
flickerstreak@185 428 end
flickerstreak@185 429
flickerstreak@185 430 function ReAction:CloseEditor()
flickerstreak@185 431 if self.editor then
flickerstreak@185 432 self.editor:Close()
flickerstreak@185 433 end
flickerstreak@185 434 end
flickerstreak@185 435
flickerstreak@185 436 function ReAction:RefreshEditor()
flickerstreak@185 437 if self.editor then
flickerstreak@185 438 self.editor:RefreshBarOptions()
flickerstreak@185 439 end
flickerstreak@185 440 end
flickerstreak@185 441
flickerstreak@185 442 function ReAction:RegisterBarOptionGenerator( module, func )
flickerstreak@185 443 if not module or type(module) ~= "table" then -- doesn't need to be a proper module, strictly
flickerstreak@185 444 error("ReAction:RegisterBarOptionGenerator() : Invalid module")
flickerstreak@185 445 end
flickerstreak@185 446 if type(func) == "string" then
flickerstreak@185 447 if not module[func] then
flickerstreak@185 448 error(("ReAction:RegisterBarOptionGenerator() : Invalid method '%s'"):format(func))
flickerstreak@185 449 end
flickerstreak@185 450 elseif func and type(func) ~= "function" then
flickerstreak@185 451 error("ReAction:RegisterBarOptionGenerator() : Invalid function")
flickerstreak@185 452 end
flickerstreak@185 453 self.barOptionGenerators = self.barOptionGenerators or { }
flickerstreak@185 454 self.barOptionGenerators[module] = func
flickerstreak@185 455
flickerstreak@185 456 if self.editor then
flickerstreak@185 457 self.editor:RefreshBarOptions()
flickerstreak@185 458 end
flickerstreak@185 459 end
flickerstreak@185 460