annotate ReAction.lua @ 230:98114c158e62

Request load of LibKeyBound-1.0 for disembedded installations
author Flick
date Tue, 22 Mar 2011 11:14:21 -0700
parents 741c4f9b251e
children 158c9299185b
rev   line source
flickerstreak@201 1 local addonName, addonTable = ...
flickerstreak@205 2 local pcall = pcall
flickerstreak@205 3 local pairs = pairs
flickerstreak@205 4 local type = type
flickerstreak@205 5 local geterrorhandler = geterrorhandler
flickerstreak@33 6 local L = LibStub("AceLocale-3.0"):GetLocale("ReAction")
Flick@230 7 local LKB = LibStub("LibKeyBound-1.0",true)
Flick@230 8 if not LKB then
Flick@230 9 LoadAddOn("LibKeyBound-1.0")
Flick@230 10 LKB = LibStub("LibKeyBound-1.0")
Flick@230 11 end
flickerstreak@33 12
flickerstreak@205 13 ------ Utility ------
flickerstreak@205 14 local tcopy
flickerstreak@28 15 do
flickerstreak@205 16 function tcopy(x)
flickerstreak@28 17 if type(x) ~= "table" then
flickerstreak@28 18 return x
flickerstreak@28 19 end
flickerstreak@28 20 local r = {}
flickerstreak@28 21 for k,v in pairs(x) do
flickerstreak@205 22 r[k] = tcopy(v)
flickerstreak@28 23 end
flickerstreak@28 24 return r
flickerstreak@28 25 end
flickerstreak@28 26 end
flickerstreak@28 27
flickerstreak@205 28 ------ Core ------
flickerstreak@205 29 local ReAction = LibStub("AceAddon-3.0"):NewAddon( "ReAction",
flickerstreak@205 30 "AceEvent-3.0"
flickerstreak@205 31 )
flickerstreak@205 32 addonTable.ReAction = ReAction
flickerstreak@205 33 ReAction.version = "1.1"
flickerstreak@205 34 ReAction.L = L
flickerstreak@205 35 ReAction.LKB = LKB
flickerstreak@28 36
flickerstreak@205 37
flickerstreak@223 38 ReAction.barTypes = { }
flickerstreak@223 39
flickerstreak@205 40 ------ Handlers ------
flickerstreak@28 41 function ReAction:OnInitialize()
flickerstreak@28 42 self.db = LibStub("AceDB-3.0"):New("ReAction_DB",
flickerstreak@213 43 self.defaultProfile,
flickerstreak@182 44 true -- use global 'Default' (locale-specific)
flickerstreak@28 45 )
flickerstreak@205 46
flickerstreak@213 47 self:UpgradeProfile()
flickerstreak@211 48
flickerstreak@205 49 self.bars = { }
flickerstreak@205 50
flickerstreak@213 51 self.LBF = LibStub("LibButtonFacade",true)
flickerstreak@213 52 if self.LBF then
flickerstreak@213 53 self.LBF:RegisterSkinCallback("ReAction", self.OnSkinChanged, self)
flickerstreak@213 54 end
flickerstreak@213 55
flickerstreak@211 56 -- It's fairly normal to use the Blizzard vehicle bar, and to have
flickerstreak@211 57 -- your regular buttons in the same location. If you do this, and don't
flickerstreak@211 58 -- bother to hide your buttons, they'll obscure some parts of the vehicle bar.
flickerstreak@211 59 VehicleMenuBar:SetFrameLevel(VehicleMenuBar:GetFrameLevel()+3)
flickerstreak@211 60
flickerstreak@205 61 self.callbacks = LibStub("CallbackHandler-1.0"):New(self)
Flick@227 62
flickerstreak@184 63 LKB.RegisterCallback(self,"LIBKEYBOUND_ENABLED")
flickerstreak@184 64 LKB.RegisterCallback(self,"LIBKEYBOUND_DISABLED")
flickerstreak@207 65 LKB.RegisterCallback(self, "LIBKEYBOUND_MODE_COLOR_CHANGED","LIBKEYBOUND_ENABLED")
Flick@227 66
Flick@227 67 -- see Profile.lua for these callback implementations
Flick@227 68 self.db.RegisterCallback(self,"OnProfileChanged")
Flick@227 69 self.db.RegisterCallback(self,"OnProfileCopied","OnProfileChanged")
Flick@227 70 self.db.RegisterCallback(self,"OnNewProfile")
Flick@227 71 self.db.RegisterCallback(self,"OnProfileReset", "OnNewProfile")
Flick@227 72
flickerstreak@182 73 self:RegisterEvent("PLAYER_REGEN_DISABLED")
Flick@227 74
flickerstreak@182 75 self:InitializeOptions()
flickerstreak@28 76 end
flickerstreak@28 77
flickerstreak@28 78 function ReAction:OnEnable()
flickerstreak@205 79 self:InitializeBars()
flickerstreak@28 80 end
flickerstreak@28 81
flickerstreak@28 82 function ReAction:OnDisable()
flickerstreak@205 83 self:TearDownBars()
flickerstreak@28 84 end
flickerstreak@28 85
flickerstreak@33 86 function ReAction:PLAYER_REGEN_DISABLED()
flickerstreak@205 87 if self.configMode == true then
flickerstreak@63 88 self:UserError(L["ReAction config mode disabled during combat."])
flickerstreak@33 89 self:SetConfigMode(false)
flickerstreak@88 90 self:SetKeybindMode(false)
flickerstreak@185 91 self:CloseEditor()
flickerstreak@33 92 end
flickerstreak@33 93 end
flickerstreak@33 94
flickerstreak@88 95 function ReAction:LIBKEYBOUND_ENABLED( evt )
flickerstreak@88 96 self:SetKeybindMode(true)
flickerstreak@88 97 end
flickerstreak@88 98
flickerstreak@88 99 function ReAction:LIBKEYBOUND_DISABLED( evt )
flickerstreak@88 100 return self:SetKeybindMode(false)
flickerstreak@88 101 end
flickerstreak@88 102
flickerstreak@213 103 function ReAction:OnSkinChanged( skinID, gloss, backdrop, group, button, colors )
flickerstreak@213 104 if group == nil then
flickerstreak@213 105 -- don't store global
flickerstreak@213 106 else
flickerstreak@213 107 -- 'group' is the bar-name
flickerstreak@213 108 local bar = self:GetBar(group)
flickerstreak@213 109 if bar then
flickerstreak@213 110 local c = bar:GetConfig().ButtonFacade
flickerstreak@213 111 if c then
flickerstreak@213 112 c.skinID = skinID
flickerstreak@213 113 c.gloss = gloss
flickerstreak@213 114 c.backdrop = backdrop
flickerstreak@213 115 c.colors = colors
flickerstreak@213 116 end
flickerstreak@213 117 end
flickerstreak@213 118 end
flickerstreak@213 119 end
flickerstreak@213 120
flickerstreak@33 121
flickerstreak@205 122 ------ Methods ------
flickerstreak@77 123
flickerstreak@61 124 function ReAction:UserError(msg)
flickerstreak@61 125 UIErrorsFrame:AddMessage(msg)
flickerstreak@61 126 end
flickerstreak@61 127
flickerstreak@205 128 function ReAction:GetBar(arg)
flickerstreak@205 129 if type(arg) == "string" then
flickerstreak@205 130 return self.bars[arg], arg
flickerstreak@205 131 elseif type(arg) == "table" then -- reverse lookup
flickerstreak@205 132 for name, bar in pairs(self.bars) do
flickerstreak@205 133 if arg == bar then
flickerstreak@205 134 return bar, name
flickerstreak@205 135 end
flickerstreak@205 136 end
flickerstreak@205 137 else
flickerstreak@205 138 error("ReAction:GetBar() requires either a name or a bar table arg")
flickerstreak@205 139 end
flickerstreak@184 140 end
flickerstreak@184 141
flickerstreak@205 142 function ReAction:IterateBars()
flickerstreak@205 143 return pairs(self.bars)
flickerstreak@205 144 end
flickerstreak@184 145
flickerstreak@63 146 -- usage:
flickerstreak@91 147 -- (1) ReAction:CreateBar(name, [cfgTable])
flickerstreak@63 148 -- (2) ReAction:CreateBar(name, "barType", [nRows], [nCols], [btnSize], [btnSpacing])
flickerstreak@91 149 function ReAction:CreateBar(name, config, ...)
flickerstreak@91 150 local profile = self.db.profile
flickerstreak@91 151
flickerstreak@217 152 name = tostring(name)
flickerstreak@217 153 if not name or name == "" then
flickerstreak@217 154 error("ReAction:CreateBar() - bar name string required")
flickerstreak@217 155 elseif self.bars[name] then
flickerstreak@217 156 self:UserError(format(L["ReAction: name '%s' already in use"],name))
flickerstreak@217 157 return nil
flickerstreak@91 158 end
flickerstreak@91 159
flickerstreak@223 160 local class
flickerstreak@91 161 if type(config) == "string" then
flickerstreak@223 162 class = self.barTypes[config]
flickerstreak@218 163 if not class then
flickerstreak@218 164 error(("ReAction:CreateBar() - unknown bar type '%s'"):format(config))
flickerstreak@48 165 end
flickerstreak@218 166 config = tcopy(class:GetDefaultBarConfig())
flickerstreak@218 167 config.btnRows = select(1,...) or config.btnRows
flickerstreak@218 168 config.btnColumns = select(2,...) or config.btnColumns
flickerstreak@218 169 config.btnWidth = select(3,...) or config.btnWidth
flickerstreak@218 170 config.btnHeight = select(3,...) or config.btnHeight
flickerstreak@218 171 config.spacing = select(4,...) or config.spacing
flickerstreak@48 172 config.width = config.width or config.btnColumns*(config.btnWidth + config.spacing) + 1
flickerstreak@48 173 config.height = config.height or config.btnRows*(config.btnHeight + config.spacing) + 1
flickerstreak@81 174 config.anchor = config.anchor or "UIParent"
flickerstreak@81 175 config.point = config.point or "BOTTOM"
flickerstreak@81 176 config.relpoint = config.relpoint or "BOTTOM"
flickerstreak@48 177 config.y = config.y or 200
flickerstreak@48 178 config.x = config.x or 0
flickerstreak@223 179 else
flickerstreak@223 180 config = config or profile.bars[name] or { }
flickerstreak@223 181 if not config or not config.type or not self.barTypes[config.type] then
flickerstreak@223 182 error(("ReAction: Unable to construct/fetch config table for bar '%s'"):format(name))
flickerstreak@223 183 end
flickerstreak@223 184 class = self.barTypes[config.type]
flickerstreak@48 185 end
flickerstreak@91 186
flickerstreak@91 187 profile.bars[name] = config
flickerstreak@91 188 local bar = self.Bar:New( name, config ) -- ReAction.Bar defined in Bar.lua
flickerstreak@205 189 self.bars[name] = bar
flickerstreak@205 190 self.callbacks:Fire("OnCreateBar", bar, name)
flickerstreak@205 191 if self.configMode then
flickerstreak@33 192 bar:ShowControls(true)
flickerstreak@33 193 end
flickerstreak@33 194
flickerstreak@28 195 return bar
flickerstreak@28 196 end
flickerstreak@28 197
flickerstreak@205 198 function ReAction:DestroyBar(x)
flickerstreak@205 199 local bar, name = self:GetBar(x)
flickerstreak@63 200 if bar and name then
flickerstreak@205 201 self.bars[name] = nil
flickerstreak@205 202 self.callbacks:Fire("OnDestroyBar", bar, name)
flickerstreak@205 203 bar:Destroy()
flickerstreak@28 204 end
flickerstreak@28 205 end
flickerstreak@28 206
flickerstreak@205 207 function ReAction:RefreshBar(x)
flickerstreak@205 208 local bar, name = self:GetBar(x)
flickerstreak@205 209 if bar and name then
flickerstreak@205 210 self.callbacks:Fire("OnRefreshBar", bar, name)
flickerstreak@205 211 end
flickerstreak@63 212 end
flickerstreak@63 213
flickerstreak@205 214 function ReAction:InitializeBars()
flickerstreak@205 215 if not self.barsInitialized then
flickerstreak@211 216 self:ManageBlizzardBars()
flickerstreak@211 217
flickerstreak@205 218 for name, config in pairs(self.db.profile.bars) do
flickerstreak@205 219 if config then
flickerstreak@205 220 self:CreateBar(name, config)
flickerstreak@205 221 end
flickerstreak@205 222 end
flickerstreak@205 223 -- re-anchor and refresh in case anchor order does not match init order
flickerstreak@205 224 for name, bar in pairs(self.bars) do
flickerstreak@205 225 bar:ApplyAnchor()
flickerstreak@205 226 self.callbacks:Fire("OnRefreshBar", bar, name)
flickerstreak@205 227 end
flickerstreak@205 228 self.barsInitialized = true
flickerstreak@205 229 end
flickerstreak@205 230 end
flickerstreak@205 231
flickerstreak@205 232 function ReAction:TearDownBars()
flickerstreak@205 233 for name, bar in pairs(self.bars) do
flickerstreak@205 234 if bar then
flickerstreak@208 235 self.bars[name] = self:DestroyBar(bar)
flickerstreak@205 236 end
flickerstreak@205 237 end
flickerstreak@205 238 self.barsInitialized = false
flickerstreak@205 239 end
flickerstreak@205 240
flickerstreak@205 241 function ReAction:RebuildAll()
flickerstreak@205 242 self:TearDownBars()
flickerstreak@205 243 self:InitializeBars()
flickerstreak@28 244 end
flickerstreak@28 245
flickerstreak@28 246 function ReAction:RenameBar(x, newname)
flickerstreak@205 247 local bar, name = self:GetBar(x)
flickerstreak@63 248 if type(newname) ~= "string" then
flickerstreak@63 249 error("ReAction:RenameBar() - second argument must be a string")
flickerstreak@63 250 end
flickerstreak@63 251 if bar and name and #newname > 0 then
flickerstreak@127 252 if newname == name then
flickerstreak@127 253 return
flickerstreak@127 254 end
flickerstreak@205 255 if self.bars[newname] then
flickerstreak@127 256 self:UserError(format(L["ReAction: name '%s' already in use"],newname))
flickerstreak@47 257 else
flickerstreak@205 258 self.bars[newname], self.bars[name] = self.bars[name], nil
flickerstreak@47 259 bar:SetName(newname or "")
flickerstreak@47 260 local cfg = self.db.profile.bars
flickerstreak@47 261 cfg[newname], cfg[name] = cfg[name], nil
flickerstreak@205 262 self.callbacks:Fire("OnRenameBar", bar, name, newname)
flickerstreak@28 263 end
flickerstreak@28 264 end
flickerstreak@28 265 end
flickerstreak@28 266
flickerstreak@205 267 function ReAction:EraseBar(x)
flickerstreak@205 268 local bar, name = self:GetBar(x)
flickerstreak@63 269 if bar and name then
flickerstreak@205 270 self.callbacks:Fire("OnEraseBar", bar, name)
flickerstreak@208 271 self:DestroyBar(bar)
flickerstreak@205 272 self.db.profile.bars[name] = nil
flickerstreak@63 273 end
flickerstreak@63 274 end
flickerstreak@63 275
flickerstreak@211 276 local blizzFrames = {
flickerstreak@211 277 MainMenuBar,
flickerstreak@211 278 MultiBarLeft,
flickerstreak@211 279 MultiBarRight,
flickerstreak@211 280 MultiBarBottomLeft,
flickerstreak@211 281 MultiBarBottomRight,
flickerstreak@211 282 }
flickerstreak@211 283
flickerstreak@211 284 local hideFrame = CreateFrame("Frame")
flickerstreak@211 285 hideFrame:Hide()
flickerstreak@211 286 local hiddenParents = { }
flickerstreak@211 287 local function ManageBlizzFrame(f, hide)
flickerstreak@211 288 if hide and not hiddenParents[f] then
flickerstreak@211 289 hiddenParents[f] = f:GetParent()
flickerstreak@211 290 f:SetParent(hideFrame)
flickerstreak@211 291 elseif not hide and hiddenParents[f] then
flickerstreak@211 292 f:SetParent(hiddenParents[f])
flickerstreak@211 293 hiddenParents[f] = nil
flickerstreak@211 294 if f:IsShown() then
flickerstreak@211 295 f:Show() -- refresh
flickerstreak@211 296 end
flickerstreak@211 297 end
flickerstreak@211 298 end
flickerstreak@211 299
flickerstreak@211 300 function ReAction:ManageBlizzardBars()
flickerstreak@211 301 for _, f in pairs(blizzFrames) do
flickerstreak@211 302 ManageBlizzFrame(f, self.db.profile.options.hideBlizzardBars)
flickerstreak@211 303 end
flickerstreak@211 304 ManageBlizzFrame(VehicleMenuBar, self.db.profile.options.hideBlizzardVehicleBar)
flickerstreak@211 305 end
flickerstreak@211 306
flickerstreak@218 307 function ReAction:RegisterBarType( class, isDefault )
flickerstreak@218 308 local name = class:GetBarType()
flickerstreak@218 309 self.barTypes[name] = class
flickerstreak@218 310 if isDefault then
flickerstreak@218 311 self.defaultBarType = name
flickerstreak@48 312 end
flickerstreak@185 313 self:RefreshEditor()
flickerstreak@48 314 end
flickerstreak@48 315
flickerstreak@63 316 function ReAction:IterateBarTypes()
flickerstreak@218 317 return pairs(self.barTypes)
flickerstreak@63 318 end
flickerstreak@63 319
flickerstreak@218 320 function ReAction:GetDefaultBarConfig(barType)
flickerstreak@218 321 if barType and self.barTypes[barType] then
flickerstreak@218 322 return self.barTypes[barType]:GetDefaultBarConfig()
flickerstreak@63 323 end
flickerstreak@63 324 end
flickerstreak@63 325
flickerstreak@63 326 function ReAction:GetBarTypeOptions( fill )
flickerstreak@63 327 fill = fill or { }
flickerstreak@63 328 for k in self:IterateBarTypes() do
flickerstreak@63 329 fill[k] = k
flickerstreak@63 330 end
flickerstreak@63 331 return fill
flickerstreak@63 332 end
flickerstreak@63 333
flickerstreak@63 334 function ReAction:GetDefaultBarType()
flickerstreak@218 335 return self.defaultBarType
flickerstreak@63 336 end
flickerstreak@63 337
flickerstreak@33 338 function ReAction:SetConfigMode( mode )
flickerstreak@205 339 if mode ~= self.configMode then
flickerstreak@207 340 if mode then
flickerstreak@207 341 self:SetKeybindMode(false)
flickerstreak@207 342 end
flickerstreak@205 343 self.configMode = mode
flickerstreak@205 344 self.callbacks:Fire("OnConfigModeChanged", mode)
flickerstreak@77 345 end
flickerstreak@63 346 end
flickerstreak@63 347
flickerstreak@63 348 function ReAction:GetConfigMode()
flickerstreak@205 349 return self.configMode
flickerstreak@33 350 end
flickerstreak@38 351
flickerstreak@88 352 function ReAction:SetKeybindMode( mode )
flickerstreak@205 353 if mode ~= self.kbMode then
flickerstreak@88 354 if mode then
flickerstreak@207 355 self:SetConfigMode(false)
flickerstreak@184 356 LKB:Activate()
flickerstreak@88 357 else
flickerstreak@184 358 LKB:Deactivate()
flickerstreak@88 359 end
flickerstreak@207 360 for _, bar in self:IterateBars() do
flickerstreak@207 361 bar:SetKeybindMode(mode)
flickerstreak@207 362 end
flickerstreak@205 363 self.kbMode = LKB:IsShown() or false
flickerstreak@88 364 end
flickerstreak@88 365 end
flickerstreak@88 366
flickerstreak@88 367 function ReAction:GetKeybindMode( mode )
flickerstreak@205 368 return self.kbMode
flickerstreak@88 369 end
Flick@225 370
Flick@225 371
Flick@225 372 -- ConfigMode support
Flick@225 373 CONFIGMODE_CALLBACKS = CONFIGMODE_CALLBACKS or {}
Flick@225 374
Flick@225 375 function CONFIGMODE_CALLBACKS.ReAction( action, mode )
Flick@225 376 if action == "ON" then
Flick@225 377 ReAction:SetConfigMode(true)
Flick@225 378 elseif action == "OFF" then
Flick@225 379 ReAction:SetConfigMode(false)
Flick@225 380 elseif action == "LISTMODES" then
Flick@225 381 -- no modes
Flick@225 382 end
Flick@225 383 end
Flick@225 384