Mercurial > wow > reaction
comparison modules/Config.lua @ 109:410d036c43b2
- reorganize modularity file structure (part 1)
| author | Flick <flickerstreak@gmail.com> |
|---|---|
| date | Thu, 08 Jan 2009 00:57:27 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 108:b2fb8f7dc780 | 109:410d036c43b2 |
|---|---|
| 1 --[[ | |
| 2 ReAction Configuration UI module | |
| 3 | |
| 4 Hooks into Blizzard Interface Options AddOns panel | |
| 5 --]] | |
| 6 | |
| 7 -- local imports | |
| 8 local ReAction = ReAction | |
| 9 local L = ReAction.L | |
| 10 local _G = _G | |
| 11 local AceConfigReg = LibStub("AceConfigRegistry-3.0") | |
| 12 local AceConfigDialog = LibStub("AceConfigDialog-3.0") | |
| 13 | |
| 14 ReAction:UpdateRevision("$Revision$") | |
| 15 | |
| 16 -- some constants | |
| 17 local configName = "ReAction" | |
| 18 | |
| 19 -- module declaration | |
| 20 local moduleID = "ConfigUI" | |
| 21 local module = ReAction:NewModule( moduleID, | |
| 22 "AceEvent-3.0" | |
| 23 ) | |
| 24 | |
| 25 -- module methods | |
| 26 function module:OnInitialize() | |
| 27 self.db = ReAction.db:RegisterNamespace( moduleID, | |
| 28 { | |
| 29 profile = { | |
| 30 closeOnLaunch = true, | |
| 31 editorCloseOnLaunch = true, | |
| 32 } | |
| 33 } | |
| 34 ) | |
| 35 | |
| 36 self:RegisterEvent("PLAYER_REGEN_DISABLED") | |
| 37 ReAction.RegisterCallback(self,"OnOptionsRegistered","OnOptionsRefreshed") | |
| 38 ReAction.RegisterCallback(self,"OnOptionsRefreshed") | |
| 39 self:InitializeOptions() | |
| 40 end | |
| 41 | |
| 42 function module:OnOptionsRefreshed(evt) | |
| 43 AceConfigReg:NotifyChange(configName) | |
| 44 if self.editor then self.editor:Refresh() end | |
| 45 end | |
| 46 | |
| 47 function module:PLAYER_REGEN_DISABLED() | |
| 48 if self.editor then | |
| 49 self.editor:Hide() | |
| 50 end | |
| 51 end | |
| 52 | |
| 53 function module:OpenConfig() | |
| 54 InterfaceOptionsFrame_OpenToCategory(configName) | |
| 55 end | |
| 56 | |
| 57 function module:InitializeOptions() | |
| 58 ReAction:RegisterOptions(self, { | |
| 59 _launchEditor = { | |
| 60 type = "execute", | |
| 61 handler = self, | |
| 62 name = L["Edit Bars..."], | |
| 63 desc = L["Show the ReAction Bar Editor dialogue"], | |
| 64 func = function() | |
| 65 self:LaunchBarEditor() | |
| 66 -- you can't close a dialog in response to an options click, because the end of the | |
| 67 -- handler for all the button events calls lib:Open() | |
| 68 -- So, schedule a close on the next OnUpdate | |
| 69 if self.db.profile.closeOnLaunch then | |
| 70 self.editor.closePending = true | |
| 71 end | |
| 72 end, | |
| 73 order = 2, | |
| 74 }, | |
| 75 _closeThis = { | |
| 76 type = "toggle", | |
| 77 name = L["Close on Launch"], | |
| 78 desc = L["Close the Interface Options window when launching the ReAction Bar Editor"], | |
| 79 get = function() return self.db.profile.closeOnLaunch end, | |
| 80 set = function(info, val) self.db.profile.closeOnLaunch = val end, | |
| 81 order = 3, | |
| 82 }, | |
| 83 _keybind = { | |
| 84 type = "execute", | |
| 85 handler = self, | |
| 86 name = L["Key Bindings"], | |
| 87 desc = L["Show the keybinding dialogue"], | |
| 88 func = function() | |
| 89 ReAction:SetKeybindMode(true) | |
| 90 end, | |
| 91 order = 4, | |
| 92 }, | |
| 93 }, true) -- global | |
| 94 | |
| 95 AceConfigReg:RegisterOptionsTable(configName,ReAction.options) | |
| 96 self.frame = AceConfigDialog:AddToBlizOptions(configName, configName) | |
| 97 self.frame.obj:SetCallback("default", | |
| 98 function() | |
| 99 ReAction.db:ResetProfile() | |
| 100 ReAction:RefreshOptions() | |
| 101 end ) | |
| 102 end | |
| 103 | |
| 104 | |
| 105 | |
| 106 | |
| 107 -- Bar Editor -- | |
| 108 local function NewEditor() | |
| 109 -- private variables | |
| 110 local editorName = "ReAction-Editor" | |
| 111 local barOptMap = setmetatable({},{__mode="v"}) | |
| 112 local tmp = { } | |
| 113 local pointTable = { | |
| 114 CENTER = L["Center"], | |
| 115 LEFT = L["Left"], | |
| 116 RIGHT = L["Right"], | |
| 117 TOP = L["Top"], | |
| 118 BOTTOM = L["Bottom"], | |
| 119 TOPLEFT = L["Top Left"], | |
| 120 TOPRIGHT = L["Top Right"], | |
| 121 BOTTOMLEFT = L["Bottom Left"], | |
| 122 BOTTOMRIGHT = L["Bottom Right"], | |
| 123 } | |
| 124 | |
| 125 | |
| 126 -- use a local GUI container to work around AceConfigDialog closing | |
| 127 -- both the bar editor and the global options when interface options is closed | |
| 128 local editor = LibStub("AceGUI-3.0"):Create("Frame") | |
| 129 local frame = editor.frame | |
| 130 frame:SetClampedToScreen(true) | |
| 131 frame:Hide() | |
| 132 local old_OnUpdate = frame:GetScript("OnUpdate") | |
| 133 frame:SetScript("OnUpdate", function(dt) | |
| 134 if old_OnUpdate then | |
| 135 old_OnUpdate(dt) | |
| 136 end | |
| 137 if editor.closePending then | |
| 138 InterfaceOptionsFrame:Hide() | |
| 139 editor.closePending = false | |
| 140 end | |
| 141 if editor.selfClosePending then | |
| 142 editor:Hide() | |
| 143 AceConfigReg:NotifyChange(configName) | |
| 144 editor.selfClosePending = false | |
| 145 end | |
| 146 end ) | |
| 147 editor:SetCallback("OnClose", | |
| 148 function() | |
| 149 ReAction:SetConfigMode(false) | |
| 150 end ) | |
| 151 AceConfigDialog:SetDefaultSize(editorName, 700, 540) | |
| 152 | |
| 153 | |
| 154 local name = ("ReAction - %s"):format(L["Bar Editor"]) | |
| 155 editor:SetTitle(name) | |
| 156 local options = { | |
| 157 type = "group", | |
| 158 name = name, | |
| 159 handler = editor, | |
| 160 childGroups = "tree", | |
| 161 args = { | |
| 162 desc = { | |
| 163 type = "description", | |
| 164 name = L["Use the mouse to arrange and resize the bars on screen. Tooltips on bars indicate additional functionality."], | |
| 165 order = 1 | |
| 166 }, | |
| 167 launchConfig = { | |
| 168 type = "execute", | |
| 169 name = L["Global Config"], | |
| 170 desc = L["Opens ReAction global configuration settings panel"], | |
| 171 func = function() | |
| 172 module:OpenConfig() | |
| 173 -- you can't close a dialog in response to an options click, because the end of the | |
| 174 -- handler for all the button events calls lib:Open() | |
| 175 -- So, schedule a close on the next OnUpdate | |
| 176 if module.db.profile.editorCloseOnLaunch then | |
| 177 editor.selfClosePending = true | |
| 178 end | |
| 179 end, | |
| 180 order = 2 | |
| 181 }, | |
| 182 closeThis = { | |
| 183 type = "toggle", | |
| 184 name = L["Close on Launch"], | |
| 185 desc = L["Close the Bar Editor when opening the ReAction global Interface Options"], | |
| 186 get = function() return module.db.profile.editorCloseOnLaunch end, | |
| 187 set = function(info, val) module.db.profile.editorCloseOnLaunch = val end, | |
| 188 order = 3, | |
| 189 }, | |
| 190 new = { | |
| 191 type = "group", | |
| 192 name = L["New Bar..."], | |
| 193 order = 4, | |
| 194 args = { | |
| 195 desc = { | |
| 196 type = "description", | |
| 197 name = L["Choose a name, type, and initial grid for your new action bar:"], | |
| 198 order = 1, | |
| 199 }, | |
| 200 name = { | |
| 201 type = "input", | |
| 202 name = L["Bar Name"], | |
| 203 desc = L["Enter a name for your new action bar"], | |
| 204 get = function() return tmp.barName or "" end, | |
| 205 set = function(info, val) tmp.barName = val end, | |
| 206 order = 2, | |
| 207 }, | |
| 208 type = { | |
| 209 type = "select", | |
| 210 name = L["Button Type"], | |
| 211 get = function() return tmp.barType or ReAction:GetDefaultBarType() or "" end, | |
| 212 set = function(info, val) | |
| 213 local c = ReAction:GetBarTypeConfig(val) | |
| 214 tmp.barType = val | |
| 215 tmp.barSize = c.defaultButtonSize or tmp.barSize | |
| 216 tmp.barRows = c.defaultBarRows or tmp.barRows | |
| 217 tmp.barCols = c.defaultBarCols or tmp.barCols | |
| 218 tmp.barSpacing = c.defaultBarSpacing or tmp.barSpacing | |
| 219 end, | |
| 220 values = "GetBarTypes", | |
| 221 order = 3, | |
| 222 }, | |
| 223 grid = { | |
| 224 type = "group", | |
| 225 name = L["Button Grid"], | |
| 226 inline = true, | |
| 227 args = { | |
| 228 hdr = { | |
| 229 type = "header", | |
| 230 name = L["Button Grid"], | |
| 231 order = 1, | |
| 232 }, | |
| 233 rows = { | |
| 234 type = "range", | |
| 235 name = L["Rows"], | |
| 236 get = function() return tmp.barRows or 1 end, | |
| 237 set = function(info, val) tmp.barRows = val end, | |
| 238 width = "half", | |
| 239 min = 1, | |
| 240 max = 32, | |
| 241 step = 1, | |
| 242 order = 2, | |
| 243 }, | |
| 244 cols = { | |
| 245 type = "range", | |
| 246 name = L["Columns"], | |
| 247 get = function() return tmp.barCols or 12 end, | |
| 248 set = function(info, val) tmp.barCols = val end, | |
| 249 width = "half", | |
| 250 min = 1, | |
| 251 max = 32, | |
| 252 step = 1, | |
| 253 order = 3, | |
| 254 }, | |
| 255 sz = { | |
| 256 type = "range", | |
| 257 name = L["Size"], | |
| 258 get = function() return tmp.barSize or 36 end, | |
| 259 set = function(info, val) tmp.barSize = val end, | |
| 260 width = "half", | |
| 261 min = 10, | |
| 262 max = 72, | |
| 263 step = 1, | |
| 264 order = 4, | |
| 265 }, | |
| 266 spacing = { | |
| 267 type = "range", | |
| 268 name = L["Spacing"], | |
| 269 get = function() return tmp.barSpacing or 3 end, | |
| 270 set = function(info, val) tmp.barSpacing = val end, | |
| 271 width = "half", | |
| 272 min = 0, | |
| 273 max = 24, | |
| 274 step = 1, | |
| 275 order = 5, | |
| 276 } | |
| 277 }, | |
| 278 order = 4 | |
| 279 }, | |
| 280 spacer = { | |
| 281 type = "header", | |
| 282 name = "", | |
| 283 width = "full", | |
| 284 order = -2 | |
| 285 }, | |
| 286 go = { | |
| 287 type = "execute", | |
| 288 name = L["Create Bar"], | |
| 289 func = "CreateBar", | |
| 290 order = -1, | |
| 291 } | |
| 292 } | |
| 293 } | |
| 294 } | |
| 295 } | |
| 296 AceConfigReg:RegisterOptionsTable(editorName, options) | |
| 297 | |
| 298 function editor:Open(bar, ...) | |
| 299 if not frame:IsVisible() then | |
| 300 AceConfigDialog:Open(editorName,self) | |
| 301 end | |
| 302 if bar then | |
| 303 AceConfigDialog:SelectGroup(editorName, barOptMap[bar:GetName()], ...) | |
| 304 end | |
| 305 end | |
| 306 | |
| 307 function editor:Refresh() | |
| 308 AceConfigReg:NotifyChange(editorName) | |
| 309 end | |
| 310 | |
| 311 function editor:CreateBarTree(bar) | |
| 312 local name = bar:GetName() | |
| 313 -- AceConfig doesn't allow spaces, etc, in arg key names, and they must be | |
| 314 -- unique strings. So generate a unique key (it can be whatever) for the bar | |
| 315 local args = options.args | |
| 316 local key | |
| 317 local i = 1 | |
| 318 repeat | |
| 319 key = ("bar%s"):format(i) | |
| 320 i = i+1 | |
| 321 until args[key] == nil | |
| 322 barOptMap[name] = key | |
| 323 args[key] = { | |
| 324 type = "group", | |
| 325 name = name, | |
| 326 childGroups = "tab", | |
| 327 args = { | |
| 328 general = { | |
| 329 type = "group", | |
| 330 name = L["General"], | |
| 331 order = 1, | |
| 332 args = { | |
| 333 name = { | |
| 334 type = "input", | |
| 335 name = L["Rename Bar"], | |
| 336 get = function() return bar:GetName() end, | |
| 337 set = function(info, value) return ReAction:RenameBar(bar, value) end, | |
| 338 order = 1, | |
| 339 }, | |
| 340 delete = { | |
| 341 type = "execute", | |
| 342 name = L["Delete Bar"], | |
| 343 desc = function() return bar:GetName() end, | |
| 344 confirm = true, | |
| 345 func = function() ReAction:EraseBar(bar) end, | |
| 346 order = 2 | |
| 347 }, | |
| 348 anchor = { | |
| 349 type = "group", | |
| 350 name = L["Anchor"], | |
| 351 inline = true, | |
| 352 args = { | |
| 353 frame = { | |
| 354 type = "input", | |
| 355 name = L["Frame"], | |
| 356 desc = L["The frame that the bar is anchored to"], | |
| 357 get = function() local _, f = bar:GetAnchor(); return f end, | |
| 358 set = function(info, val) bar:SetAnchor(nil,val) end, | |
| 359 validate = function(info, name) | |
| 360 if name then | |
| 361 local f = ReAction:GetBar(name) | |
| 362 if f then | |
| 363 return true | |
| 364 else | |
| 365 f = _G[name] | |
| 366 if f and type(f) == "table" and f.IsObjectType and f:IsObjectType("Frame") then | |
| 367 local _, explicit = f:IsProtected() | |
| 368 return explicit | |
| 369 end | |
| 370 end | |
| 371 end | |
| 372 return false | |
| 373 end, | |
| 374 width = "double", | |
| 375 order = 1 | |
| 376 }, | |
| 377 point = { | |
| 378 type = "select", | |
| 379 name = L["Point"], | |
| 380 desc = L["Anchor point on the bar frame"], | |
| 381 style = "dropdown", | |
| 382 get = function() return bar:GetAnchor() end, | |
| 383 set = function(info, val) bar:SetAnchor(val) end, | |
| 384 values = pointTable, | |
| 385 order = 2, | |
| 386 }, | |
| 387 relativePoint = { | |
| 388 type = "select", | |
| 389 name = L["Relative Point"], | |
| 390 desc = L["Anchor point on the target frame"], | |
| 391 style = "dropdown", | |
| 392 get = function() local p,f,r = bar:GetAnchor(); return r end, | |
| 393 set = function(info, val) bar:SetAnchor(nil,nil,val) end, | |
| 394 values = pointTable, | |
| 395 order = 3, | |
| 396 }, | |
| 397 x = { | |
| 398 type = "input", | |
| 399 pattern = "\-?%d+", | |
| 400 name = L["X offset"], | |
| 401 get = function() local p,f,r,x = bar:GetAnchor(); return ("%d"):format(x) end, | |
| 402 set = function(info,val) bar:SetAnchor(nil,nil,nil,val) end, | |
| 403 order = 4 | |
| 404 }, | |
| 405 y = { | |
| 406 type = "input", | |
| 407 pattern = "\-?%d+", | |
| 408 name = L["Y offset"], | |
| 409 get = function() local p,f,r,x,y = bar:GetAnchor(); return ("%d"):format(y) end, | |
| 410 set = function(info,val) bar:SetAnchor(nil,nil,nil,nil,val) end, | |
| 411 order = 5 | |
| 412 }, | |
| 413 }, | |
| 414 order = 3 | |
| 415 }, | |
| 416 alpha = { | |
| 417 type = "range", | |
| 418 name = L["Transparency"], | |
| 419 get = function() return bar:GetAlpha() end, | |
| 420 set = function(info, val) bar:SetAlpha(val) end, | |
| 421 min = 0, | |
| 422 max = 1, | |
| 423 isPercent = true, | |
| 424 step = 0.01, | |
| 425 bigStep = 0.05, | |
| 426 order = 4, | |
| 427 }, | |
| 428 }, | |
| 429 }, | |
| 430 } | |
| 431 } | |
| 432 self:RefreshBarTree(bar) | |
| 433 end | |
| 434 | |
| 435 function editor:RefreshBarTree(bar) | |
| 436 local key = barOptMap[bar:GetName()] | |
| 437 if key and options.args[key] then | |
| 438 options.args[key].plugins = ReAction:GenerateBarOptionsTable(bar) | |
| 439 AceConfigReg:NotifyChange(editorName) | |
| 440 end | |
| 441 end | |
| 442 | |
| 443 function editor:OnCreateBar(evt, bar) | |
| 444 if not tmp.creating then | |
| 445 -- a bit of hack to work around OnCreateBar event handler ordering | |
| 446 self:CreateBarTree(bar) | |
| 447 end | |
| 448 end | |
| 449 | |
| 450 function editor:OnDestroyBar(evt, bar, name) | |
| 451 local key = barOptMap[name] | |
| 452 if key then | |
| 453 options.args[key] = nil | |
| 454 end | |
| 455 self:Refresh() | |
| 456 end | |
| 457 | |
| 458 function editor:OnEraseBar(evt, name) | |
| 459 local key = barOptMap[name] | |
| 460 barOptMap[name] = nil | |
| 461 if key then | |
| 462 options.args[key] = nil | |
| 463 self:Refresh() | |
| 464 end | |
| 465 end | |
| 466 | |
| 467 function editor:OnRenameBar(evt, bar, oldname, newname) | |
| 468 local key = barOptMap[oldname] | |
| 469 barOptMap[oldname], barOptMap[newname] = nil, key | |
| 470 if key then | |
| 471 options.args[key].name = newname | |
| 472 self:Refresh() | |
| 473 end | |
| 474 end | |
| 475 | |
| 476 function editor:OnBarOptionGeneratorRegistered(evt) | |
| 477 for name in pairs(barOptMap) do | |
| 478 local bar = ReAction:GetBar(name) | |
| 479 if bar then | |
| 480 self:RefreshBarTree(bar) | |
| 481 end | |
| 482 end | |
| 483 end | |
| 484 | |
| 485 local _scratch = { } | |
| 486 function editor:GetBarTypes() | |
| 487 for k,v in pairs(_scratch) do | |
| 488 _scratch[k] = nil | |
| 489 end | |
| 490 return ReAction:GetBarTypeOptions(_scratch) | |
| 491 end | |
| 492 | |
| 493 function editor:CreateBar() | |
| 494 if tmp.barName and tmp.barName ~= "" then | |
| 495 tmp.creating = true | |
| 496 local bar = ReAction:CreateBar(tmp.barName, tmp.barType or ReAction:GetDefaultBarType(), tmp.barRows, tmp.barCols, tmp.barSize, tmp.barSpacing) | |
| 497 self:CreateBarTree(bar) | |
| 498 AceConfigDialog:SelectGroup(editorName, barOptMap[tmp.barName]) | |
| 499 tmp.barName = nil | |
| 500 tmp.creating = false | |
| 501 end | |
| 502 end | |
| 503 | |
| 504 ReAction.RegisterCallback(editor,"OnCreateBar") | |
| 505 ReAction.RegisterCallback(editor,"OnDestroyBar") | |
| 506 ReAction.RegisterCallback(editor,"OnEraseBar") | |
| 507 ReAction.RegisterCallback(editor,"OnRenameBar") | |
| 508 ReAction.RegisterCallback(editor,"OnBarOptionGeneratorRegistered") | |
| 509 | |
| 510 for name, bar in ReAction:IterateBars() do | |
| 511 editor:CreateBarTree(bar) | |
| 512 end | |
| 513 | |
| 514 return editor | |
| 515 end | |
| 516 | |
| 517 | |
| 518 function module:LaunchBarEditor(bar, ...) | |
| 519 if InCombatLockdown() then | |
| 520 ReAction:UserError(L["ReAction config mode disabled during combat."]) | |
| 521 else | |
| 522 if not self.editor then | |
| 523 self.editor = NewEditor() | |
| 524 end | |
| 525 self.editor:Open(bar, ...) | |
| 526 ReAction:SetConfigMode(true) | |
| 527 end | |
| 528 end | |
| 529 |
