annotate main.lua @ 7:f920db5fc6b1

version 0.3
author Flick <flickerstreak@gmail.com>
date Tue, 20 Mar 2007 21:25:29 +0000
parents dfd829db3ad0
children c05fd3e18b4f
rev   line source
flickerstreak@7 1 -- main.lua
flickerstreak@1 2 --
flickerstreak@1 3 -- Top-level file for the ReAction Action Bar add-on
flickerstreak@1 4 --
flickerstreak@7 5 -- implemented in terms of the Ace 2 development framework library: http://www.wowace.com
flickerstreak@1 6 --
flickerstreak@1 7
flickerstreak@7 8 -- Ace Library local object initialization
flickerstreak@7 9 local L = AceLibrary("AceLocale-2.2"):new("ReAction")
flickerstreak@7 10 local dewdrop = AceLibrary("Dewdrop-2.0")
flickerstreak@7 11 local tablet = AceLibrary("Tablet-2.0")
flickerstreak@1 12
flickerstreak@7 13 -- private functions
flickerstreak@2 14 local function tcopy(t)
flickerstreak@2 15 local r = { }
flickerstreak@2 16 for k, v in pairs(t) do
flickerstreak@2 17 r[k] = (type(v) == "table" and tcopy(v) or v)
flickerstreak@2 18 end
flickerstreak@2 19 return r
flickerstreak@2 20 end
flickerstreak@2 21
flickerstreak@7 22 -- private constants
flickerstreak@7 23 local EMPTY_BAR_SLOT = -1
flickerstreak@7 24
flickerstreak@7 25 -- key binding label constants
flickerstreak@7 26 BINDING_HEADER_REACTION = L["ReAction"]
flickerstreak@7 27 BINDING_NAME_REACTION_TOGGLELOCK = L["Toggle ReAction Bar Lock"]
flickerstreak@7 28 BINDING_NAME_REBOUND_TOGGLEBINDINGMODE = L["Toggle ReBound Keybinding Mode"]
flickerstreak@7 29
flickerstreak@7 30
flickerstreak@7 31 -- main object
flickerstreak@7 32 local main = AceLibrary("AceAddon-2.0"):new(
flickerstreak@7 33 "AceConsole-2.0",
flickerstreak@7 34 "AceEvent-2.0",
flickerstreak@7 35 "AceDB-2.0",
flickerstreak@7 36 "FuBarPlugin-2.0"
flickerstreak@7 37 )
flickerstreak@1 38
flickerstreak@1 39 -- initial non-persistent state
flickerstreak@7 40 main.locked = true
flickerstreak@1 41
flickerstreak@7 42 -- set a global variable for Bindings.xml
flickerstreak@7 43 ReActionAddOn = main
flickerstreak@7 44
flickerstreak@7 45
flickerstreak@7 46 -- FuBar plugin setup
flickerstreak@7 47 -- Even if FuBar isn't installed, this gives us a nice minimap-button interface.
flickerstreak@7 48 main.hasIcon = "Interface\\Icons\\INV_Qiraj_JewelEncased"
flickerstreak@7 49 main.hasNoColor = true
flickerstreak@7 50 main.hideMenuTitle = true
flickerstreak@7 51 main.defaultPosition = "LEFT"
flickerstreak@7 52 main.defaultMinimapPosition = 240 -- degrees
flickerstreak@7 53 main.OnMenuRequest = tcopy(ReActionGlobalMenuOptions) -- use a copy, or bar menus will have FuBar inserted items
flickerstreak@7 54 main.independentProfile = true
flickerstreak@7 55
flickerstreak@7 56 -- set the handler for the global bar menu options
flickerstreak@7 57 -- have to do this after tcopy() above, otherwise it will try to copy the handler object (bad idea)
flickerstreak@7 58 ReActionGlobalMenuOptions.handler = main
flickerstreak@7 59
flickerstreak@1 60
flickerstreak@1 61
flickerstreak@1 62
flickerstreak@1 63 -- Event handling
flickerstreak@7 64 function main:OnInitialize()
flickerstreak@7 65 self:RegisterChatCommand( {L["/reaction"], L["/rxn"]}, ReActionConsoleOptions, "REACTION" )
flickerstreak@1 66 self:RegisterDB("ReActionDB","ReActionDBPC")
flickerstreak@7 67 self:RegisterDefaults("profile", ReAction_DefaultProfile)
flickerstreak@1 68 self:RegisterEvent("PLAYER_REGEN_DISABLED","CombatLockdown")
flickerstreak@2 69 self:RegisterEvent("PLAYER_ENTERING_WORLD","HideDefaultBars")
flickerstreak@7 70 self:RegisterEvent("EVENT_REBOUND_KEYBINDING_MODE")
flickerstreak@1 71 end
flickerstreak@1 72
flickerstreak@7 73 function main:OnEnable()
flickerstreak@7 74 -- this gets called at startup and when the profile is changed
flickerstreak@1 75 if self.db.profile.firstRunDone ~= true then
flickerstreak@1 76 -- Do some "first-run" setup
flickerstreak@7 77 self:StealKeyBindings()
flickerstreak@1 78 self.db.profile.firstRunDone = true
flickerstreak@7 79 self.db.profile.bars = tcopy(ReAction_DefaultBlizzardBars)
flickerstreak@1 80 end
flickerstreak@7 81 self:DestroyAllBars()
flickerstreak@2 82 self:SetupBars()
flickerstreak@1 83 end
flickerstreak@1 84
flickerstreak@7 85 function main:OnDisable()
flickerstreak@1 86 self:Lock()
flickerstreak@1 87 end
flickerstreak@1 88
flickerstreak@7 89 function main:OnProfileEnable()
flickerstreak@7 90 -- for profile switching
flickerstreak@7 91 self:OnEnable()
flickerstreak@1 92 end
flickerstreak@1 93
flickerstreak@7 94 function main:CombatLockdown()
flickerstreak@1 95 if not self:IsLocked() then
flickerstreak@1 96 self:Lock()
flickerstreak@7 97 ReBound:Disable()
flickerstreak@7 98 UIErrorsFrame:AddMessage(L["ReAction bars locked when in combat"])
flickerstreak@1 99 end
flickerstreak@1 100 end
flickerstreak@1 101
flickerstreak@7 102 function main:EVENT_REBOUND_KEYBINDING_MODE(enabled)
flickerstreak@7 103 for _, bar in pairs(self.bars) do
flickerstreak@7 104 for __, button in pairs(bar.buttons) do
flickerstreak@7 105 button:TempShow(enabled)
flickerstreak@7 106 end
flickerstreak@7 107 end
flickerstreak@7 108 end
flickerstreak@1 109
flickerstreak@7 110
flickerstreak@7 111 -- FuBar plugin methods
flickerstreak@7 112 function main:OnTooltipUpdate()
flickerstreak@7 113 local c = tablet:AddCategory("columns", 2)
flickerstreak@7 114 c:AddLine("text", L["Bar lock"], "text2", self.locked and ("|cffff0000"..L["Locked"].."|r") or ("|cffffcc00"..L["Unlocked"].."|r"))
flickerstreak@7 115 c:AddLine("text", L["Button lock"], "text2", LOCK_ACTIONBAR == "1" and ("|cffcc0000"..L["Locked"].."|r") or ("|cff00cc00"..L["Unlocked"].."|r"))
flickerstreak@7 116 c:AddLine("text", L["Kebinding mode"], "text2", ReBound:IsEnabled() and ("|cff33ff33"..L["On"].."|r") or ("|cffffcc00"..L["Off"].."|r"))
flickerstreak@7 117 tablet:SetHint(L["|cffffcc00Shift-Click for bar lock|n|cff33ff33Alt-Click|r for keybindings|nRight-click for menu"])
flickerstreak@7 118 end
flickerstreak@7 119
flickerstreak@7 120 function main:OnClick(button)
flickerstreak@7 121 if IsShiftKeyDown() then
flickerstreak@7 122 self:ToggleLocked()
flickerstreak@7 123 self:UpdateDisplay()
flickerstreak@7 124 elseif IsAltKeyDown() then
flickerstreak@7 125 ReBound:ToggleEnabled()
flickerstreak@7 126 self:UpdateDisplay()
flickerstreak@7 127 end
flickerstreak@7 128 end
flickerstreak@7 129
flickerstreak@7 130
flickerstreak@7 131 -- lock/unlock bars
flickerstreak@7 132 function main:SetLocked( lock )
flickerstreak@2 133 if lock ~= self.locked then
flickerstreak@2 134 if not lock and InCombatLockdown() then
flickerstreak@2 135 UIErrorsFrame:AddMessage(SPELL_FAILED_AFFECTING_COMBAT)
flickerstreak@2 136 else
flickerstreak@2 137 self.locked = lock and true or false -- force data integrity
flickerstreak@2 138 for _, bar in pairs(self.bars) do
flickerstreak@7 139 if bar ~= EMPTY_BAR_SLOT then
flickerstreak@7 140 if self.locked then
flickerstreak@7 141 bar:HideControls()
flickerstreak@7 142 -- close any dewdrop menu owned by the bar
flickerstreak@7 143 if bar:GetControlFrame() == dewdrop:GetOpenedParent() then
flickerstreak@7 144 dewdrop:Close()
flickerstreak@7 145 end
flickerstreak@7 146 else
flickerstreak@7 147 bar:ShowControls()
flickerstreak@7 148 end
flickerstreak@7 149 end
flickerstreak@2 150 end
flickerstreak@2 151 end
flickerstreak@1 152 end
flickerstreak@1 153 end
flickerstreak@1 154
flickerstreak@7 155 function main:IsLocked()
flickerstreak@1 156 return self.locked
flickerstreak@1 157 end
flickerstreak@1 158
flickerstreak@7 159 function main:Lock()
flickerstreak@1 160 self:SetLocked(true)
flickerstreak@1 161 end
flickerstreak@1 162
flickerstreak@7 163 function main:Unlock()
flickerstreak@1 164 self:SetLocked(false)
flickerstreak@1 165 end
flickerstreak@1 166
flickerstreak@7 167 function main:ToggleLocked()
flickerstreak@7 168 main:SetLocked( not(self.locked) )
flickerstreak@1 169 end
flickerstreak@1 170
flickerstreak@1 171
flickerstreak@1 172
flickerstreak@1 173 -- Hide the default Blizzard main bar artwork
flickerstreak@7 174 function main:HideArt()
flickerstreak@1 175 if self.db.profile.hideArt then
flickerstreak@7 176 -- the pet bar is a child of MainMenuBar, and can't be hidden. Need to reparent it
flickerstreak@7 177 PetActionBarFrame:SetParent(UIParent)
flickerstreak@1 178 MainMenuBar:Hide() -- this also hides the bags, xp bar, lag meter, and micro menu buttons.
flickerstreak@7 179 -- these two are the pet bar background
flickerstreak@7 180 -- unfortunately UIParent_ManageFramePositions() shows and hides these too
flickerstreak@7 181 -- so they get reparented to MainMenuBar
flickerstreak@7 182 SlidingActionBarTexture0:SetParent(MainMenuBar)
flickerstreak@7 183 SlidingActionBarTexture1:SetParent(MainMenuBar)
flickerstreak@1 184 else
flickerstreak@7 185 SlidingActionBarTexture0:SetParent(PetActionBarFrame)
flickerstreak@7 186 SlidingActionBarTexture1:SetParent(PetActionBarFrame)
flickerstreak@1 187 MainMenuBar:Show()
flickerstreak@1 188 end
flickerstreak@1 189 end
flickerstreak@1 190
flickerstreak@7 191 function main:IsArtHidden()
flickerstreak@1 192 return self.db.profile.hideArt
flickerstreak@1 193 end
flickerstreak@1 194
flickerstreak@7 195 function main:SetHideArt( hide )
flickerstreak@2 196 if InCombatLockdown() then
flickerstreak@2 197 UIErrorsFrame:AddMessage(SPELL_FAILED_AFFECTING_COMBAT)
flickerstreak@2 198 else
flickerstreak@2 199 self.db.profile.hideArt = hide and true or false -- force data integrity
flickerstreak@2 200 self:HideArt()
flickerstreak@2 201 end
flickerstreak@1 202 end
flickerstreak@1 203
flickerstreak@7 204 function main:ToggleHideArt()
flickerstreak@1 205 self:SetHideArt( not self:IsArtHidden() )
flickerstreak@1 206 end
flickerstreak@1 207
flickerstreak@1 208
flickerstreak@1 209
flickerstreak@1 210 -- Hide default Blizzard bars
flickerstreak@1 211 local blizzDefaultBars = {
flickerstreak@1 212 ActionButton1,
flickerstreak@1 213 ActionButton2,
flickerstreak@1 214 ActionButton3,
flickerstreak@1 215 ActionButton4,
flickerstreak@1 216 ActionButton5,
flickerstreak@1 217 ActionButton6,
flickerstreak@1 218 ActionButton7,
flickerstreak@1 219 ActionButton8,
flickerstreak@1 220 ActionButton9,
flickerstreak@1 221 ActionButton10,
flickerstreak@1 222 ActionButton11,
flickerstreak@1 223 ActionButton12,
flickerstreak@7 224 PetActionButton1,
flickerstreak@7 225 PetActionButton2,
flickerstreak@7 226 PetActionButton3,
flickerstreak@7 227 PetActionButton4,
flickerstreak@7 228 PetActionButton5,
flickerstreak@7 229 PetActionButton6,
flickerstreak@7 230 PetActionButton7,
flickerstreak@7 231 PetActionButton8,
flickerstreak@7 232 PetActionButton9,
flickerstreak@7 233 PetActionButton10,
flickerstreak@7 234 -- NOT the PetActionBarFrame, though - we need that to auto-hide/show our pet action bars
flickerstreak@7 235 MainMenuBarPageNumber,
flickerstreak@7 236 ActionBarUpButton,
flickerstreak@7 237 ActionBarDownButton,
flickerstreak@1 238 BonusActionBarFrame,
flickerstreak@7 239 ShapeshiftBarFrame,
flickerstreak@1 240 MultiBarLeft,
flickerstreak@1 241 MultiBarRight,
flickerstreak@1 242 MultiBarBottomLeft,
flickerstreak@7 243 MultiBarBottomRight,
flickerstreak@1 244 }
flickerstreak@1 245
flickerstreak@7 246 function main:StealKeyBindings()
flickerstreak@7 247 -- steal the keybindings of the main action bar and assign them to rebar 1, buttons 1-12
flickerstreak@7 248 for i = 1, 12 do
flickerstreak@7 249 -- TODO: when we convert to override bindings
flickerstreak@1 250 end
flickerstreak@1 251 end
flickerstreak@1 252
flickerstreak@7 253 local function disableUIOptions()
flickerstreak@7 254 -- disable the buttons to hide/show the blizzard multiaction bars
flickerstreak@7 255 -- see UIOptionsFrame.lua and .xml
flickerstreak@7 256 -- This is called every time the options panel is shown, after it is set up
flickerstreak@7 257 for _, idx in pairs( { 33, 34, 35, 36, 37, 40 } ) do
flickerstreak@7 258 local f = getglobal("UIOptionsFrameCheckButton"..idx)
flickerstreak@7 259 f.disabled = true
flickerstreak@7 260 OptionsFrame_DisableCheckBox(f)
flickerstreak@7 261 f:SetChecked(false)
flickerstreak@7 262 end
flickerstreak@7 263 end
flickerstreak@1 264
flickerstreak@7 265 function main:HideDefaultBars()
flickerstreak@7 266 for _, f in pairs(blizzDefaultBars) do
flickerstreak@7 267 f:Hide()
flickerstreak@7 268 f:ClearAllPoints()
flickerstreak@7 269 f:SetParent(ReAction.recycler)
flickerstreak@7 270 f:SetPoint("TOPLEFT")
flickerstreak@7 271 end
flickerstreak@7 272
flickerstreak@7 273 MainMenuBar:SetFrameStrata("LOW") -- otherwise it appears on top of bars, if it isn't hidden
flickerstreak@7 274 hooksecurefunc("UIOptionsFrame_Load",disableUIOptions)
flickerstreak@7 275 end
flickerstreak@7 276
flickerstreak@7 277
flickerstreak@7 278 -- Reset bars to blizzard defaults
flickerstreak@7 279 function main:ResetBars()
flickerstreak@2 280 if InCombatLockdown() then
flickerstreak@2 281 UIErrorsFrame:AddMessage(SPELL_FAILED_AFFECTING_COMBAT)
flickerstreak@2 282 else
flickerstreak@7 283 self:DestroyAllBars()
flickerstreak@7 284 self.db.profile.bars = tcopy(ReAction_DefaultBlizzardBars)
flickerstreak@2 285 self:SetupBars()
flickerstreak@2 286 end
flickerstreak@1 287 end
flickerstreak@1 288
flickerstreak@1 289
flickerstreak@1 290 -- re-sync action IDs
flickerstreak@7 291 function main:ResyncActionIDs()
flickerstreak@1 292 -- TODO
flickerstreak@1 293 end
flickerstreak@1 294
flickerstreak@1 295
flickerstreak@1 296
flickerstreak@1 297 -- Bar manipulation
flickerstreak@7 298 main.bars = { }
flickerstreak@1 299
flickerstreak@7 300 function main:DestroyAllBars()
flickerstreak@7 301 -- destroy any existing bars
flickerstreak@7 302 for id = 1, table.maxn(self.bars) do
flickerstreak@7 303 self:DestroyBar(id)
flickerstreak@7 304 end
flickerstreak@7 305 end
flickerstreak@7 306
flickerstreak@7 307
flickerstreak@7 308 function main:SetupBars()
flickerstreak@1 309 -- hide the default Blizzard art, if configued
flickerstreak@1 310 self:HideArt()
flickerstreak@1 311
flickerstreak@1 312 -- set up the bars from the profile
flickerstreak@2 313 -- note the use of table.maxn rather than # or ipairs:
flickerstreak@2 314 -- our array of bars can in fact contain holes
flickerstreak@2 315 for id = 1, table.maxn(self.db.profile.bars) do
flickerstreak@2 316 local config = self.db.profile.bars[id]
flickerstreak@2 317 if config then
flickerstreak@7 318 self:CreateBar(config, id)
flickerstreak@2 319 end
flickerstreak@1 320 end
flickerstreak@1 321
flickerstreak@1 322 -- anchor the bars, have to do this in a second pass because
flickerstreak@1 323 -- they might be anchored to each other in a non-ordered way
flickerstreak@2 324 for _, bar in pairs(self.bars) do
flickerstreak@7 325 if bar ~= EMPTY_BAR_SLOT then
flickerstreak@7 326 bar:ApplyAnchor()
flickerstreak@2 327 end
flickerstreak@2 328 end
flickerstreak@1 329 end
flickerstreak@1 330
flickerstreak@7 331 function main:CreateBar( config, id )
flickerstreak@7 332 local bar = ReBar:new(config, id)
flickerstreak@7 333 local buttonType = ReAction:GetButtonType(config.btnConfig.subtype)
flickerstreak@1 334
flickerstreak@7 335 if buttonType then
flickerstreak@7 336 self.bars[id] = bar
flickerstreak@7 337 self.db.profile.bars[id] = config
flickerstreak@7 338
flickerstreak@7 339 -- initialize dewdrop menu
flickerstreak@7 340 local cf = bar:GetControlFrame()
flickerstreak@7 341 dewdrop:Register(cf,
flickerstreak@7 342 'children',
flickerstreak@7 343 function()
flickerstreak@7 344 dewdrop:FeedAceOptionsTable(ReActionGlobalMenuOptions)
flickerstreak@7 345 dewdrop:FeedAceOptionsTable(GenerateReActionBarOptions(bar,self))
flickerstreak@7 346 dewdrop:FeedAceOptionsTable(buttonType:GenerateOptionsTable(config.btnConfig, function() return bar:GetButtonList() end))
flickerstreak@7 347 end,
flickerstreak@7 348 'cursorX', true,
flickerstreak@7 349 'cursorY', true
flickerstreak@7 350 )
flickerstreak@7 351
flickerstreak@7 352 bar:GetControlFrame():SetScript("OnClick",
flickerstreak@7 353 function(btn)
flickerstreak@7 354 if btn == "RightButton" then
flickerstreak@7 355 dewdrop:Open(cf)
flickerstreak@7 356 end
flickerstreak@7 357 end
flickerstreak@7 358 )
flickerstreak@7 359
flickerstreak@7 360 if not self.locked then
flickerstreak@7 361 bar:ShowControls()
flickerstreak@7 362 end
flickerstreak@7 363 return bar
flickerstreak@7 364 else
flickerstreak@7 365 if bar then
flickerstreak@7 366 bar:Destroy()
flickerstreak@7 367 end
flickerstreak@7 368 error(L["Tried to create a button of unknown type"])
flickerstreak@7 369 end
flickerstreak@7 370 end
flickerstreak@7 371
flickerstreak@7 372 function main:DestroyBar( id )
flickerstreak@7 373 local bar = self.bars[id]
flickerstreak@7 374 if bar and bar ~= EMPTY_BAR_SLOT then
flickerstreak@7 375 local cf = bar:GetControlFrame()
flickerstreak@7 376 if cf == dewdrop:GetOpenedParent() then
flickerstreak@7 377 dewdrop:Close()
flickerstreak@7 378 dewdrop:Unregister(cf)
flickerstreak@7 379 end
flickerstreak@7 380 bar:Destroy()
flickerstreak@7 381 -- we can't do tremove because each bar ID is encoded into the
flickerstreak@7 382 -- frame names as they're created. Need a blank entry in the table.
flickerstreak@7 383 -- The nice thing is that table.insert in NewBar() will automatically
flickerstreak@7 384 -- find the lowest numbered nil slot.
flickerstreak@7 385 self.bars[id] = EMPTY_BAR_SLOT
flickerstreak@7 386 end
flickerstreak@7 387 end
flickerstreak@7 388
flickerstreak@7 389 function main:NewBar( type )
flickerstreak@7 390 if InCombatLockdown() then
flickerstreak@7 391 UIErrorsFrame:AddMessage(SPELL_FAILED_AFFECTING_COMBAT)
flickerstreak@7 392 else
flickerstreak@7 393 local t = ReAction:GetButtonType(type)
flickerstreak@7 394 if t then
flickerstreak@7 395 local c = tcopy(ReAction_DefaultBarConfig["ReAction"][type])
flickerstreak@7 396 local id = nil
flickerstreak@7 397 for i = 1, table.maxn(self.bars) + 1 do -- there may be holes, so #self.bars won't work
flickerstreak@7 398 if self.bars[i] == nil or self.bars[i] == EMPTY_BAR_SLOT then
flickerstreak@7 399 id = i
flickerstreak@7 400 break
flickerstreak@7 401 end
flickerstreak@7 402 end
flickerstreak@7 403 local bar = self:CreateBar(c, id)
flickerstreak@7 404 bar:ApplyAnchor()
flickerstreak@7 405 self:Unlock()
flickerstreak@7 406 end
flickerstreak@7 407 end
flickerstreak@7 408 end
flickerstreak@7 409
flickerstreak@7 410
flickerstreak@7 411 function main:DeleteBar(id)
flickerstreak@2 412 if InCombatLockdown() then
flickerstreak@2 413 UIErrorsFrame:AddMessage(SPELL_FAILED_AFFECTING_COMBAT)
flickerstreak@2 414 else
flickerstreak@2 415 if self.bars[id] then
flickerstreak@7 416 self:DestroyBar(id)
flickerstreak@2 417 self.db.profile.bars[id] = nil
flickerstreak@2 418 end
flickerstreak@1 419 end
flickerstreak@1 420 end
flickerstreak@1 421
flickerstreak@7 422 function main:ToggleIds()
flickerstreak@7 423 if self.showIds then
flickerstreak@7 424 ReAction:HideAllIds()
flickerstreak@1 425 else
flickerstreak@7 426 ReAction:ShowAllIds()
flickerstreak@1 427 end
flickerstreak@7 428 self.showIds = not self.showIds
flickerstreak@1 429 end
flickerstreak@1 430
flickerstreak@7 431 function main:AreIdsVisible()
flickerstreak@7 432 return self.showIds
flickerstreak@1 433 end
flickerstreak@1 434
flickerstreak@1 435
flickerstreak@1 436