annotate ReAction.lua @ 48:7b7d178dec52

Implemented bar-type selection, extended CreateBar functionality
author Flick <flickerstreak@gmail.com>
date Sat, 12 Apr 2008 00:15:09 +0000
parents e12b736c23c3
children c3c64e2def50
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@28 44 elseif ReAction.Bar:IsInstance(x) then
flickerstreak@28 45 bar = x
flickerstreak@28 46 for k,v in pairs(ReAction.bars) do
flickerstreak@28 47 if v == bar then
flickerstreak@28 48 name = k
flickerstreak@28 49 end
flickerstreak@28 50 end
flickerstreak@28 51 else
flickerstreak@28 52 error("bad argument to SelectBar")
flickerstreak@28 53 end
flickerstreak@28 54 return bar, name
flickerstreak@28 55 end
flickerstreak@28 56
flickerstreak@28 57 DestroyBar = function(x)
flickerstreak@28 58 local bar, name = SelectBar(x)
flickerstreak@28 59 if name and bar then
flickerstreak@28 60 ReAction.bars[name] = nil
flickerstreak@28 61 ReAction:CallMethodOnAllModules("RemoveFromBar", bar)
flickerstreak@28 62 bar:Destroy()
flickerstreak@28 63 end
flickerstreak@28 64 end
flickerstreak@28 65
flickerstreak@28 66 InitializeBars = function ()
flickerstreak@28 67 if not(ReAction.inited) then
flickerstreak@28 68 for name, config in pairs(ReAction.db.profile.bars) do
flickerstreak@28 69 if config then
flickerstreak@28 70 ReAction:CreateBar(name, config)
flickerstreak@28 71 end
flickerstreak@28 72 end
flickerstreak@28 73 ReAction:CallMethodOnAllBars("ApplyAnchor") -- re-anchor in the case of oddball ordering
flickerstreak@28 74 ReAction.inited = true
flickerstreak@28 75 end
flickerstreak@28 76 end
flickerstreak@28 77
flickerstreak@28 78 TearDownBars = function()
flickerstreak@28 79 for name, bar in pairs(ReAction.bars) do
flickerstreak@28 80 if bar then
flickerstreak@28 81 ReAction.bars[name] = DestroyBar(bar)
flickerstreak@28 82 end
flickerstreak@28 83 end
flickerstreak@28 84 ReAction.inited = false
flickerstreak@28 85 end
flickerstreak@28 86
flickerstreak@28 87 DeepCopy = function(x)
flickerstreak@28 88 if type(x) ~= "table" then
flickerstreak@28 89 return x
flickerstreak@28 90 end
flickerstreak@28 91 local r = {}
flickerstreak@28 92 for k,v in pairs(x) do
flickerstreak@28 93 r[k] = DeepCopy(v)
flickerstreak@28 94 end
flickerstreak@28 95 return r
flickerstreak@28 96 end
flickerstreak@28 97
flickerstreak@28 98 SafeCall = function(f, ...)
flickerstreak@28 99 if f then
flickerstreak@28 100 local success, err = pcall(f,...)
flickerstreak@28 101 if not success then
flickerstreak@28 102 geterrorhandler()(err)
flickerstreak@28 103 end
flickerstreak@28 104 end
flickerstreak@28 105 end
flickerstreak@28 106
flickerstreak@28 107 CheckMethod = function(m)
flickerstreak@28 108 if type(m) == "function" then
flickerstreak@28 109 return m
flickerstreak@28 110 end
flickerstreak@28 111 if type(m) ~= "string" then
flickerstreak@28 112 error("Invalid method")
flickerstreak@28 113 end
flickerstreak@28 114 end
flickerstreak@30 115
flickerstreak@30 116 SlashHandler = function(option)
flickerstreak@30 117 if option == "config" then
flickerstreak@38 118 ReAction:ShowConfig()
flickerstreak@47 119 elseif option == "layout" then
flickerstreak@47 120 ReAction:ShowLayout()
flickerstreak@30 121 else
flickerstreak@36 122 ReAction:Print(("%3.1f.%d"):format(ReAction.version,ReAction.revision))
flickerstreak@30 123 ReAction:Print("/reaction config")
flickerstreak@47 124 ReAction:Print("/reaction layout")
flickerstreak@30 125 end
flickerstreak@30 126 end
flickerstreak@28 127 end
flickerstreak@28 128
flickerstreak@28 129
flickerstreak@28 130 ------ HANDLERS ------
flickerstreak@28 131 function ReAction:OnInitialize()
flickerstreak@28 132 self.db = LibStub("AceDB-3.0"):New("ReAction_DB",
flickerstreak@28 133 {
flickerstreak@28 134 profile = {
flickerstreak@28 135 bars = { },
flickerstreak@28 136 defaultBar = { }
flickerstreak@28 137 }
flickerstreak@28 138 }
flickerstreak@28 139 -- default profile is character-specific
flickerstreak@28 140 )
flickerstreak@28 141 self.db.RegisterCallback(self,"OnProfileChanged")
flickerstreak@43 142 self.db.RegisterCallback(self,"OnProfileReset","OnProfileChanged")
flickerstreak@30 143 self.callbacks = LibStub("CallbackHandler-1.0"):New(self)
flickerstreak@30 144 self:RegisterChatCommand("reaction", SlashHandler)
flickerstreak@30 145 self:RegisterChatCommand("rxn", SlashHandler)
flickerstreak@33 146 self:RegisterEvent("PLAYER_REGEN_DISABLED")
flickerstreak@28 147
flickerstreak@28 148 self.bars = {}
flickerstreak@46 149 self.options = {}
flickerstreak@48 150 self.defaultBarConfig = {}
flickerstreak@46 151
flickerstreak@46 152 self:RegisterOptions("global", self, {
flickerstreak@46 153 unlock = {
flickerstreak@46 154 type = "toggle",
flickerstreak@46 155 handler = module,
flickerstreak@46 156 name = L["Unlock Bars"],
flickerstreak@46 157 desc = L["Unlock bars for dragging and resizing with the mouse"],
flickerstreak@46 158 get = function() return self.configMode end,
flickerstreak@46 159 set = function(info, value) self:SetConfigMode(value) end,
flickerstreak@46 160 disabled = InCombatLockdown,
flickerstreak@46 161 order = 1
flickerstreak@46 162 },
flickerstreak@46 163 })
flickerstreak@46 164
flickerstreak@28 165 end
flickerstreak@28 166
flickerstreak@28 167 function ReAction:OnEnable()
flickerstreak@28 168 InitializeBars()
flickerstreak@28 169 end
flickerstreak@28 170
flickerstreak@28 171 function ReAction:OnDisable()
flickerstreak@28 172 TearDownBars()
flickerstreak@28 173 end
flickerstreak@28 174
flickerstreak@28 175 function ReAction:OnProfileChanged()
flickerstreak@33 176 TearDownBars()
flickerstreak@33 177 InitializeBars()
flickerstreak@28 178 end
flickerstreak@28 179
flickerstreak@28 180 function ReAction:OnModuleEnable(module)
flickerstreak@28 181 if module.ApplyToBar then
flickerstreak@28 182 for _, b in pairs(bars) do
flickerstreak@28 183 if b then
flickerstreak@28 184 module:ApplyToBar(b)
flickerstreak@28 185 end
flickerstreak@28 186 end
flickerstreak@28 187 end
flickerstreak@28 188 end
flickerstreak@28 189
flickerstreak@28 190 function ReAction:OnModuleDisable(module)
flickerstreak@28 191 if module.RemoveFromBar then
flickerstreak@28 192 for _, b in pairs(bars) do
flickerstreak@28 193 if b then
flickerstreak@28 194 module:RemoveFromBar(b)
flickerstreak@28 195 end
flickerstreak@28 196 end
flickerstreak@28 197 end
flickerstreak@28 198 end
flickerstreak@28 199
flickerstreak@33 200 function ReAction:PLAYER_REGEN_DISABLED()
flickerstreak@33 201 if self.configMode == true then
flickerstreak@33 202 UIErrorsFrame:AddMessage(L["ReAction config mode disabled during combat."])
flickerstreak@33 203 self:SetConfigMode(false)
flickerstreak@33 204 end
flickerstreak@33 205 end
flickerstreak@33 206
flickerstreak@33 207
flickerstreak@28 208
flickerstreak@28 209 ------ API ------
flickerstreak@28 210 function ReAction:CallMethodOnAllModules(method, ...)
flickerstreak@28 211 local m = CheckMethod(method)
flickerstreak@28 212 for _, x in self:IterateModules() do
flickerstreak@28 213 if x then
flickerstreak@28 214 SafeCall(m or x[method], x, ...)
flickerstreak@28 215 end
flickerstreak@28 216 end
flickerstreak@28 217 end
flickerstreak@28 218
flickerstreak@28 219 function ReAction:CallMethodOnAllBars(method,...)
flickerstreak@28 220 local m = CheckMethod(method)
flickerstreak@28 221 for _, x in pairs(self.bars) do
flickerstreak@28 222 if x then
flickerstreak@28 223 SafeCall(m or x[method], x, ...)
flickerstreak@28 224 end
flickerstreak@28 225 end
flickerstreak@28 226 end
flickerstreak@28 227
flickerstreak@38 228 function ReAction:CallModuleMethod(modulename, method, ...)
flickerstreak@38 229 local m = self:GetModule(modulename,true)
flickerstreak@38 230 if not m then
flickerstreak@38 231 LoadAddOn(("ReAction_%s"):format(modulename))
flickerstreak@38 232 m = self:GetModule(modulename,true)
flickerstreak@43 233 if m then
flickerstreak@43 234 dbprint(("succesfully loaded LOD module: %s"):format(modulename))
flickerstreak@43 235 end
flickerstreak@38 236 end
flickerstreak@38 237 if m then
flickerstreak@38 238 if type(m) == "table" and type(m[method]) == "function" then
flickerstreak@38 239 m[method](m,...)
flickerstreak@38 240 else
flickerstreak@38 241 dbprint(("Bad call '%s' to %s module"):format(tostring(method),modulename));
flickerstreak@38 242 end
flickerstreak@38 243 else
flickerstreak@38 244 self:Print(("Module '%s' not found"):format(tostring(modulename)))
flickerstreak@38 245 end
flickerstreak@38 246 end
flickerstreak@38 247
flickerstreak@38 248
flickerstreak@48 249 function ReAction:CreateBar(name, ...)
flickerstreak@48 250 local config = select(1,...)
flickerstreak@48 251 if config and type(config) ~= "table" then
flickerstreak@48 252 bartype = select(1,...)
flickerstreak@48 253 if type(bartype) ~= "string" then
flickerstreak@48 254 error("ReAction:CreateBar() - first argument must be a config table or a default config type string")
flickerstreak@48 255 end
flickerstreak@48 256 config = self.defaultBarConfig[bartype]
flickerstreak@48 257 if not config then
flickerstreak@48 258 error(("ReAction:CreateBar() - unknown bar type '%s'"):format(bartype))
flickerstreak@48 259 end
flickerstreak@48 260 config = DeepCopy(config)
flickerstreak@48 261 config.btnRows = select(2,...) or config.btnRows or 1
flickerstreak@48 262 config.btnColumns = select(3,...) or config.btnColumns or 12
flickerstreak@48 263 config.btnWidth = select(4,...) or config.btnWidth or 36
flickerstreak@48 264 config.btnHeight = select(4,...) or config.btnHeight or 36
flickerstreak@48 265 config.spacing = select(5,...) or config.spacing or 3
flickerstreak@48 266 config.width = config.width or config.btnColumns*(config.btnWidth + config.spacing) + 1
flickerstreak@48 267 config.height = config.height or config.btnRows*(config.btnHeight + config.spacing) + 1
flickerstreak@48 268 config.anchor = config.anchor or "BOTTOM"
flickerstreak@48 269 config.anchorTo = config.anchorTo or "UIParent"
flickerstreak@48 270 config.relativePoint = config.relativePoint or "BOTTOM"
flickerstreak@48 271 config.y = config.y or 200
flickerstreak@48 272 config.x = config.x or 0
flickerstreak@48 273 end
flickerstreak@28 274 local profile = self.db.profile
flickerstreak@48 275 config = config or DeepCopy(profile.defaultBar)
flickerstreak@28 276 prefix = prefix or L["Bar "]
flickerstreak@28 277 if not name then
flickerstreak@28 278 i = 1
flickerstreak@28 279 repeat
flickerstreak@28 280 name = prefix..i
flickerstreak@28 281 i = i + 1
flickerstreak@28 282 until self.bars[name] == nil
flickerstreak@28 283 end
flickerstreak@48 284 profile.bars[name] = profile.bars[name] or config
flickerstreak@28 285 local bar = self.Bar:new( name, profile.bars[name] ) -- ReAction.Bar defined in Bar.lua
flickerstreak@28 286 self:CallMethodOnAllModules("ApplyToBar", bar)
flickerstreak@28 287 self.bars[name] = bar
flickerstreak@30 288 self.callbacks:Fire("OnCreateBar", bar)
flickerstreak@33 289 if self.configMode then
flickerstreak@33 290 bar:ShowControls(true)
flickerstreak@33 291 end
flickerstreak@33 292
flickerstreak@28 293 return bar
flickerstreak@28 294 end
flickerstreak@28 295
flickerstreak@28 296 function ReAction:EraseBar(x)
flickerstreak@28 297 local bar, name = SelectBar(x)
flickerstreak@28 298 if name and bar then
flickerstreak@28 299 DestroyBar(bar)
flickerstreak@28 300 self.db.profile.bars[name] = nil
flickerstreak@28 301 self:CallMethodOnAllModules("EraseBarConfig", name)
flickerstreak@30 302 self.callbacks:Fire("OnEraseBar",name)
flickerstreak@28 303 end
flickerstreak@28 304 end
flickerstreak@28 305
flickerstreak@28 306 function ReAction:GetBar(name)
flickerstreak@28 307 return self.bars[name]
flickerstreak@28 308 end
flickerstreak@28 309
flickerstreak@28 310 function ReAction:RenameBar(x, newname)
flickerstreak@28 311 local bar, name = SelectBar(x)
flickerstreak@28 312 if bar and name and newname then
flickerstreak@28 313 if self.bars[newname] then
flickerstreak@47 314 UIErrorsFrame:AddMessage(("%s ('%s')"):format(L["ReAction: name already in use"],newname))
flickerstreak@47 315 else
flickerstreak@47 316 self.bars[newname] = self.bars[name]
flickerstreak@47 317 self.bars[name] = nil
flickerstreak@47 318 bar:SetName(newname or "")
flickerstreak@47 319 local cfg = self.db.profile.bars
flickerstreak@47 320 cfg[newname], cfg[name] = cfg[name], nil
flickerstreak@47 321 self:CallMethodOnAllModules("RenameBarConfig", name, newname)
flickerstreak@47 322 self.callbacks:Fire("OnRenameBar", name, newname)
flickerstreak@28 323 end
flickerstreak@28 324 end
flickerstreak@28 325 end
flickerstreak@28 326
flickerstreak@48 327 function ReAction:RegisterDefaultBarConfig( name, config, isDefaultChoice )
flickerstreak@48 328 self.defaultBarConfig[name] = config
flickerstreak@48 329 if isDefaultChoice then
flickerstreak@48 330 self.defaultBarConfigChoice = name
flickerstreak@48 331 end
flickerstreak@48 332 self:RefreshOptions()
flickerstreak@48 333 end
flickerstreak@48 334
flickerstreak@48 335 function ReAction:UnregisterDefaultBarConfig( name )
flickerstreak@48 336 self.defaultBarConfig[name] = nil
flickerstreak@48 337 if self.defaultBarConfigChoice == name then
flickerstreak@48 338 self.defaultBarConfigChoice = nil
flickerstreak@48 339 end
flickerstreak@48 340 self:RefreshOptions()
flickerstreak@48 341 end
flickerstreak@48 342
flickerstreak@30 343 -- See modules/ReAction_ConfigUI for valid options contexts.
flickerstreak@30 344 function ReAction:RegisterOptions(context, module, opts)
flickerstreak@30 345 if module == nil or context == nil then
flickerstreak@30 346 error("ReAction:RegisterOptions requires a module object and context ID")
flickerstreak@30 347 end
flickerstreak@30 348 if not self.options[context] then
flickerstreak@30 349 self.options[context] = {}
flickerstreak@30 350 end
flickerstreak@30 351 self.options[context][module] = opts
flickerstreak@30 352 self.callbacks:Fire("OnOptionsRegistered", context, module, opts)
flickerstreak@30 353 end
flickerstreak@28 354
flickerstreak@30 355 function ReAction:GetOptions(context)
flickerstreak@30 356 if context then
flickerstreak@30 357 if not self.options[context] then
flickerstreak@30 358 self.options[context] = { }
flickerstreak@30 359 end
flickerstreak@30 360 return self.options[context]
flickerstreak@30 361 end
flickerstreak@30 362 end
flickerstreak@30 363
flickerstreak@30 364 function ReAction:RefreshOptions()
flickerstreak@30 365 self.callbacks:Fire("OnOptionsRefreshed")
flickerstreak@30 366 end
flickerstreak@33 367
flickerstreak@33 368 function ReAction:SetConfigMode( mode )
flickerstreak@33 369 self:CallMethodOnAllBars("ShowControls",mode)
flickerstreak@33 370 self:CallMethodOnAllModules("ApplyConfigMode",mode,self.bars)
flickerstreak@33 371 self.configMode = mode
flickerstreak@33 372 end
flickerstreak@38 373
flickerstreak@38 374 function ReAction:ShowConfig()
flickerstreak@38 375 self:CallModuleMethod("ConfigUI","OpenConfig")
flickerstreak@38 376 end
flickerstreak@38 377
flickerstreak@47 378 function ReAction:ShowLayout()
flickerstreak@47 379 self:CallModuleMethod("ConfigUI","LaunchLayoutEditor")
flickerstreak@47 380 end