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