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