annotate ReAction.lua @ 61:2ee41dcd673f

moved UserError from ConfigUI to ReAction
author Flick <flickerstreak@gmail.com>
date Tue, 13 May 2008 16:42:03 +0000
parents 44649a10378d
children 768be7eb22a0
rev   line source
flickerstreak@28 1 -- ReAction.lua
flickerstreak@28 2 -- See modules/ReAction_ModuleTemplate for Module API listing
flickerstreak@28 3 -- See Bar.lua for Bar object listing
flickerstreak@27 4
flickerstreak@27 5 ------ CORE ------
flickerstreak@30 6 local ReAction = LibStub("AceAddon-3.0"):NewAddon( "ReAction",
flickerstreak@33 7 "AceConsole-3.0",
flickerstreak@33 8 "AceEvent-3.0"
flickerstreak@30 9 )
flickerstreak@33 10 ReAction.version = GetAddOnMetadata("ReAction","Version")
flickerstreak@33 11 ReAction.revision = tonumber(("$Revision$"):match("%d+"))
flickerstreak@27 12
flickerstreak@28 13 ------ GLOBALS ------
flickerstreak@28 14 _G["ReAction"] = ReAction
flickerstreak@27 15
flickerstreak@28 16 ------ DEBUGGING ------
flickerstreak@25 17 ReAction.debug = true
flickerstreak@36 18 local dbprint
flickerstreak@25 19 if ReAction.debug then
flickerstreak@36 20 dbprint = function(msg)
flickerstreak@25 21 DEFAULT_CHAT_FRAME:AddMessage(msg)
flickerstreak@25 22 end
flickerstreak@36 23 --seterrorhandler(dbprint)
flickerstreak@25 24 else
flickerstreak@36 25 dbprint = function() end
flickerstreak@25 26 end
flickerstreak@36 27 ReAction.dbprint = dbprint
flickerstreak@25 28
flickerstreak@33 29 ------ LIBRARIES ------
flickerstreak@33 30 local L = LibStub("AceLocale-3.0"):GetLocale("ReAction")
flickerstreak@33 31 ReAction.L = L
flickerstreak@33 32
flickerstreak@28 33 ------ PRIVATE ------
flickerstreak@30 34 local SelectBar, DestroyBar, InitializeBars, TearDownBars, DeepCopy, SafeCall, CheckMethod, SlashHandler
flickerstreak@28 35 do
flickerstreak@28 36 local pcall = pcall
flickerstreak@28 37 local geterrorhandler = geterrorhandler
flickerstreak@28 38
flickerstreak@28 39 SelectBar = function(x)
flickerstreak@28 40 local bar, name
flickerstreak@28 41 if type(x) == "string" then
flickerstreak@28 42 name = x
flickerstreak@28 43 bar = ReAction:GetBar(name)
flickerstreak@50 44 else
flickerstreak@28 45 for k,v in pairs(ReAction.bars) do
flickerstreak@50 46 if v == x then
flickerstreak@28 47 name = k
flickerstreak@50 48 bar = x
flickerstreak@28 49 end
flickerstreak@28 50 end
flickerstreak@28 51 end
flickerstreak@28 52 return bar, name
flickerstreak@28 53 end
flickerstreak@28 54
flickerstreak@28 55 DestroyBar = function(x)
flickerstreak@28 56 local bar, name = SelectBar(x)
flickerstreak@28 57 if name and bar then
flickerstreak@28 58 ReAction.bars[name] = nil
flickerstreak@28 59 ReAction:CallMethodOnAllModules("RemoveFromBar", bar)
flickerstreak@28 60 bar:Destroy()
flickerstreak@28 61 end
flickerstreak@28 62 end
flickerstreak@28 63
flickerstreak@28 64 InitializeBars = function ()
flickerstreak@28 65 if not(ReAction.inited) then
flickerstreak@28 66 for name, config in pairs(ReAction.db.profile.bars) do
flickerstreak@28 67 if config then
flickerstreak@28 68 ReAction:CreateBar(name, config)
flickerstreak@28 69 end
flickerstreak@28 70 end
flickerstreak@28 71 ReAction:CallMethodOnAllBars("ApplyAnchor") -- re-anchor in the case of oddball ordering
flickerstreak@28 72 ReAction.inited = true
flickerstreak@28 73 end
flickerstreak@28 74 end
flickerstreak@28 75
flickerstreak@28 76 TearDownBars = function()
flickerstreak@28 77 for name, bar in pairs(ReAction.bars) do
flickerstreak@28 78 if bar then
flickerstreak@28 79 ReAction.bars[name] = DestroyBar(bar)
flickerstreak@28 80 end
flickerstreak@28 81 end
flickerstreak@28 82 ReAction.inited = false
flickerstreak@28 83 end
flickerstreak@28 84
flickerstreak@28 85 DeepCopy = function(x)
flickerstreak@28 86 if type(x) ~= "table" then
flickerstreak@28 87 return x
flickerstreak@28 88 end
flickerstreak@28 89 local r = {}
flickerstreak@28 90 for k,v in pairs(x) do
flickerstreak@28 91 r[k] = DeepCopy(v)
flickerstreak@28 92 end
flickerstreak@28 93 return r
flickerstreak@28 94 end
flickerstreak@28 95
flickerstreak@28 96 SafeCall = function(f, ...)
flickerstreak@28 97 if f then
flickerstreak@28 98 local success, err = pcall(f,...)
flickerstreak@28 99 if not success then
flickerstreak@28 100 geterrorhandler()(err)
flickerstreak@28 101 end
flickerstreak@28 102 end
flickerstreak@28 103 end
flickerstreak@28 104
flickerstreak@28 105 CheckMethod = function(m)
flickerstreak@28 106 if type(m) == "function" then
flickerstreak@28 107 return m
flickerstreak@28 108 end
flickerstreak@28 109 if type(m) ~= "string" then
flickerstreak@28 110 error("Invalid method")
flickerstreak@28 111 end
flickerstreak@28 112 end
flickerstreak@30 113
flickerstreak@30 114 SlashHandler = function(option)
flickerstreak@30 115 if option == "config" then
flickerstreak@38 116 ReAction:ShowConfig()
flickerstreak@58 117 elseif option == "edit" then
flickerstreak@58 118 ReAction:ShowEditor()
flickerstreak@50 119 elseif option == "unlock" then
flickerstreak@50 120 ReAction:SetConfigMode(true)
flickerstreak@50 121 elseif option == "lock" then
flickerstreak@50 122 ReAction:SetConfigMode(false)
flickerstreak@30 123 else
flickerstreak@36 124 ReAction:Print(("%3.1f.%d"):format(ReAction.version,ReAction.revision))
flickerstreak@30 125 ReAction:Print("/reaction config")
flickerstreak@58 126 ReAction:Print("/reaction edit")
flickerstreak@50 127 ReAction:Print("/reaction lock")
flickerstreak@50 128 ReAction:Print("/reaction unlock")
flickerstreak@30 129 end
flickerstreak@30 130 end
flickerstreak@28 131 end
flickerstreak@28 132
flickerstreak@28 133
flickerstreak@28 134 ------ HANDLERS ------
flickerstreak@28 135 function ReAction:OnInitialize()
flickerstreak@28 136 self.db = LibStub("AceDB-3.0"):New("ReAction_DB",
flickerstreak@28 137 {
flickerstreak@28 138 profile = {
flickerstreak@28 139 bars = { },
flickerstreak@28 140 defaultBar = { }
flickerstreak@28 141 }
flickerstreak@28 142 }
flickerstreak@28 143 -- default profile is character-specific
flickerstreak@28 144 )
flickerstreak@28 145 self.db.RegisterCallback(self,"OnProfileChanged")
flickerstreak@43 146 self.db.RegisterCallback(self,"OnProfileReset","OnProfileChanged")
flickerstreak@30 147 self.callbacks = LibStub("CallbackHandler-1.0"):New(self)
flickerstreak@30 148 self:RegisterChatCommand("reaction", SlashHandler)
flickerstreak@30 149 self:RegisterChatCommand("rxn", SlashHandler)
flickerstreak@33 150 self:RegisterEvent("PLAYER_REGEN_DISABLED")
flickerstreak@28 151
flickerstreak@28 152 self.bars = {}
flickerstreak@48 153 self.defaultBarConfig = {}
flickerstreak@46 154
flickerstreak@60 155 self.options = {
flickerstreak@60 156 type = "group",
flickerstreak@60 157 name = "ReAction",
flickerstreak@60 158 childGroups = "tab",
flickerstreak@60 159 args = {
flickerstreak@60 160 _desc = {
flickerstreak@60 161 type = "description",
flickerstreak@60 162 name = L["Customizable replacement for Blizzard's Action Bars"],
flickerstreak@60 163 order = 1,
flickerstreak@60 164 },
flickerstreak@60 165 global = {
flickerstreak@60 166 type = "group",
flickerstreak@60 167 name = L["Global Settings"],
flickerstreak@60 168 desc = L["Global configuration settings"],
flickerstreak@60 169 args = {
flickerstreak@60 170 unlock = {
flickerstreak@60 171 type = "toggle",
flickerstreak@60 172 handler = module,
flickerstreak@60 173 name = L["Unlock Bars"],
flickerstreak@60 174 desc = L["Unlock bars for dragging and resizing with the mouse"],
flickerstreak@60 175 get = function() return self.configMode end,
flickerstreak@60 176 set = function(info, value) self:SetConfigMode(value) end,
flickerstreak@60 177 disabled = InCombatLockdown,
flickerstreak@60 178 order = 1
flickerstreak@60 179 },
flickerstreak@60 180 },
flickerstreak@60 181 plugins = { },
flickerstreak@60 182 order = 2,
flickerstreak@60 183 },
flickerstreak@60 184 module = {
flickerstreak@60 185 type = "group",
flickerstreak@60 186 childGroups = "select",
flickerstreak@60 187 name = L["Module Settings"],
flickerstreak@60 188 desc = L["Configuration settings for each module"],
flickerstreak@60 189 args = { },
flickerstreak@60 190 plugins = { },
flickerstreak@60 191 order = 3,
flickerstreak@60 192 },
flickerstreak@60 193 profile = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db)
flickerstreak@46 194 },
flickerstreak@60 195 plugins = { }
flickerstreak@60 196 }
flickerstreak@46 197
flickerstreak@28 198 end
flickerstreak@28 199
flickerstreak@28 200 function ReAction:OnEnable()
flickerstreak@28 201 InitializeBars()
flickerstreak@28 202 end
flickerstreak@28 203
flickerstreak@28 204 function ReAction:OnDisable()
flickerstreak@28 205 TearDownBars()
flickerstreak@28 206 end
flickerstreak@28 207
flickerstreak@28 208 function ReAction:OnProfileChanged()
flickerstreak@33 209 TearDownBars()
flickerstreak@33 210 InitializeBars()
flickerstreak@28 211 end
flickerstreak@28 212
flickerstreak@28 213 function ReAction:OnModuleEnable(module)
flickerstreak@28 214 if module.ApplyToBar then
flickerstreak@28 215 for _, b in pairs(bars) do
flickerstreak@28 216 if b then
flickerstreak@28 217 module:ApplyToBar(b)
flickerstreak@28 218 end
flickerstreak@28 219 end
flickerstreak@28 220 end
flickerstreak@28 221 end
flickerstreak@28 222
flickerstreak@28 223 function ReAction:OnModuleDisable(module)
flickerstreak@28 224 if module.RemoveFromBar then
flickerstreak@28 225 for _, b in pairs(bars) do
flickerstreak@28 226 if b then
flickerstreak@28 227 module:RemoveFromBar(b)
flickerstreak@28 228 end
flickerstreak@28 229 end
flickerstreak@28 230 end
flickerstreak@28 231 end
flickerstreak@28 232
flickerstreak@33 233 function ReAction:PLAYER_REGEN_DISABLED()
flickerstreak@33 234 if self.configMode == true then
flickerstreak@33 235 UIErrorsFrame:AddMessage(L["ReAction config mode disabled during combat."])
flickerstreak@33 236 self:SetConfigMode(false)
flickerstreak@33 237 end
flickerstreak@33 238 end
flickerstreak@33 239
flickerstreak@33 240
flickerstreak@28 241
flickerstreak@28 242 ------ API ------
flickerstreak@61 243 function ReAction:UserError(msg)
flickerstreak@61 244 -- any user errors should be flashed to the UIErrorsFrame
flickerstreak@61 245 UIErrorsFrame:AddMessage(msg)
flickerstreak@61 246 end
flickerstreak@61 247
flickerstreak@28 248 function ReAction:CallMethodOnAllModules(method, ...)
flickerstreak@28 249 local m = CheckMethod(method)
flickerstreak@28 250 for _, x in self:IterateModules() do
flickerstreak@28 251 if x then
flickerstreak@28 252 SafeCall(m or x[method], x, ...)
flickerstreak@28 253 end
flickerstreak@28 254 end
flickerstreak@28 255 end
flickerstreak@28 256
flickerstreak@28 257 function ReAction:CallMethodOnAllBars(method,...)
flickerstreak@28 258 local m = CheckMethod(method)
flickerstreak@28 259 for _, x in pairs(self.bars) do
flickerstreak@28 260 if x then
flickerstreak@28 261 SafeCall(m or x[method], x, ...)
flickerstreak@28 262 end
flickerstreak@28 263 end
flickerstreak@28 264 end
flickerstreak@28 265
flickerstreak@38 266 function ReAction:CallModuleMethod(modulename, method, ...)
flickerstreak@38 267 local m = self:GetModule(modulename,true)
flickerstreak@38 268 if not m then
flickerstreak@38 269 LoadAddOn(("ReAction_%s"):format(modulename))
flickerstreak@38 270 m = self:GetModule(modulename,true)
flickerstreak@43 271 if m then
flickerstreak@43 272 dbprint(("succesfully loaded LOD module: %s"):format(modulename))
flickerstreak@43 273 end
flickerstreak@38 274 end
flickerstreak@38 275 if m then
flickerstreak@38 276 if type(m) == "table" and type(m[method]) == "function" then
flickerstreak@38 277 m[method](m,...)
flickerstreak@38 278 else
flickerstreak@38 279 dbprint(("Bad call '%s' to %s module"):format(tostring(method),modulename));
flickerstreak@38 280 end
flickerstreak@38 281 else
flickerstreak@38 282 self:Print(("Module '%s' not found"):format(tostring(modulename)))
flickerstreak@38 283 end
flickerstreak@38 284 end
flickerstreak@38 285
flickerstreak@38 286
flickerstreak@48 287 function ReAction:CreateBar(name, ...)
flickerstreak@48 288 local config = select(1,...)
flickerstreak@48 289 if config and type(config) ~= "table" then
flickerstreak@48 290 bartype = select(1,...)
flickerstreak@48 291 if type(bartype) ~= "string" then
flickerstreak@48 292 error("ReAction:CreateBar() - first argument must be a config table or a default config type string")
flickerstreak@48 293 end
flickerstreak@48 294 config = self.defaultBarConfig[bartype]
flickerstreak@48 295 if not config then
flickerstreak@48 296 error(("ReAction:CreateBar() - unknown bar type '%s'"):format(bartype))
flickerstreak@48 297 end
flickerstreak@48 298 config = DeepCopy(config)
flickerstreak@48 299 config.btnRows = select(2,...) or config.btnRows or 1
flickerstreak@48 300 config.btnColumns = select(3,...) or config.btnColumns or 12
flickerstreak@48 301 config.btnWidth = select(4,...) or config.btnWidth or 36
flickerstreak@48 302 config.btnHeight = select(4,...) or config.btnHeight or 36
flickerstreak@48 303 config.spacing = select(5,...) or config.spacing or 3
flickerstreak@48 304 config.width = config.width or config.btnColumns*(config.btnWidth + config.spacing) + 1
flickerstreak@48 305 config.height = config.height or config.btnRows*(config.btnHeight + config.spacing) + 1
flickerstreak@48 306 config.anchor = config.anchor or "BOTTOM"
flickerstreak@48 307 config.anchorTo = config.anchorTo or "UIParent"
flickerstreak@48 308 config.relativePoint = config.relativePoint or "BOTTOM"
flickerstreak@48 309 config.y = config.y or 200
flickerstreak@48 310 config.x = config.x or 0
flickerstreak@48 311 end
flickerstreak@28 312 local profile = self.db.profile
flickerstreak@48 313 config = config or DeepCopy(profile.defaultBar)
flickerstreak@28 314 prefix = prefix or L["Bar "]
flickerstreak@28 315 if not name then
flickerstreak@28 316 i = 1
flickerstreak@28 317 repeat
flickerstreak@28 318 name = prefix..i
flickerstreak@28 319 i = i + 1
flickerstreak@28 320 until self.bars[name] == nil
flickerstreak@28 321 end
flickerstreak@48 322 profile.bars[name] = profile.bars[name] or config
flickerstreak@28 323 local bar = self.Bar:new( name, profile.bars[name] ) -- ReAction.Bar defined in Bar.lua
flickerstreak@28 324 self:CallMethodOnAllModules("ApplyToBar", bar)
flickerstreak@28 325 self.bars[name] = bar
flickerstreak@30 326 self.callbacks:Fire("OnCreateBar", bar)
flickerstreak@33 327 if self.configMode then
flickerstreak@33 328 bar:ShowControls(true)
flickerstreak@33 329 end
flickerstreak@33 330
flickerstreak@28 331 return bar
flickerstreak@28 332 end
flickerstreak@28 333
flickerstreak@28 334 function ReAction:EraseBar(x)
flickerstreak@28 335 local bar, name = SelectBar(x)
flickerstreak@28 336 if name and bar then
flickerstreak@28 337 DestroyBar(bar)
flickerstreak@28 338 self.db.profile.bars[name] = nil
flickerstreak@28 339 self:CallMethodOnAllModules("EraseBarConfig", name)
flickerstreak@30 340 self.callbacks:Fire("OnEraseBar",name)
flickerstreak@28 341 end
flickerstreak@28 342 end
flickerstreak@28 343
flickerstreak@28 344 function ReAction:GetBar(name)
flickerstreak@28 345 return self.bars[name]
flickerstreak@28 346 end
flickerstreak@28 347
flickerstreak@28 348 function ReAction:RenameBar(x, newname)
flickerstreak@28 349 local bar, name = SelectBar(x)
flickerstreak@28 350 if bar and name and newname then
flickerstreak@28 351 if self.bars[newname] then
flickerstreak@47 352 UIErrorsFrame:AddMessage(("%s ('%s')"):format(L["ReAction: name already in use"],newname))
flickerstreak@47 353 else
flickerstreak@47 354 self.bars[newname] = self.bars[name]
flickerstreak@47 355 self.bars[name] = nil
flickerstreak@47 356 bar:SetName(newname or "")
flickerstreak@47 357 local cfg = self.db.profile.bars
flickerstreak@47 358 cfg[newname], cfg[name] = cfg[name], nil
flickerstreak@47 359 self:CallMethodOnAllModules("RenameBarConfig", name, newname)
flickerstreak@47 360 self.callbacks:Fire("OnRenameBar", name, newname)
flickerstreak@28 361 end
flickerstreak@28 362 end
flickerstreak@28 363 end
flickerstreak@28 364
flickerstreak@53 365 function ReAction:RegisterBarType( name, config, isDefaultChoice )
flickerstreak@48 366 self.defaultBarConfig[name] = config
flickerstreak@48 367 if isDefaultChoice then
flickerstreak@48 368 self.defaultBarConfigChoice = name
flickerstreak@48 369 end
flickerstreak@48 370 self:RefreshOptions()
flickerstreak@48 371 end
flickerstreak@48 372
flickerstreak@53 373 function ReAction:UnregisterBarType( name )
flickerstreak@48 374 self.defaultBarConfig[name] = nil
flickerstreak@48 375 if self.defaultBarConfigChoice == name then
flickerstreak@48 376 self.defaultBarConfigChoice = nil
flickerstreak@48 377 end
flickerstreak@48 378 self:RefreshOptions()
flickerstreak@48 379 end
flickerstreak@48 380
flickerstreak@60 381 function ReAction:RegisterOptions(module, options, global)
flickerstreak@60 382 self.options.args[global and "global" or "module"].plugins[module:GetName()] = options
flickerstreak@30 383 end
flickerstreak@30 384
flickerstreak@30 385 function ReAction:RefreshOptions()
flickerstreak@30 386 self.callbacks:Fire("OnOptionsRefreshed")
flickerstreak@30 387 end
flickerstreak@33 388
flickerstreak@33 389 function ReAction:SetConfigMode( mode )
flickerstreak@33 390 self:CallMethodOnAllBars("ShowControls",mode)
flickerstreak@33 391 self:CallMethodOnAllModules("ApplyConfigMode",mode,self.bars)
flickerstreak@33 392 self.configMode = mode
flickerstreak@33 393 end
flickerstreak@38 394
flickerstreak@38 395 function ReAction:ShowConfig()
flickerstreak@38 396 self:CallModuleMethod("ConfigUI","OpenConfig")
flickerstreak@38 397 end
flickerstreak@38 398
flickerstreak@58 399 function ReAction:ShowEditor()
flickerstreak@58 400 self:CallModuleMethod("ConfigUI","LaunchBarEditor")
flickerstreak@47 401 end