flickerstreak@7: -- main.lua flickerstreak@1: -- flickerstreak@1: -- Top-level file for the ReAction Action Bar add-on flickerstreak@1: -- flickerstreak@7: -- implemented in terms of the Ace 2 development framework library: http://www.wowace.com flickerstreak@1: -- flickerstreak@1: flickerstreak@7: -- Ace Library local object initialization flickerstreak@7: local L = AceLibrary("AceLocale-2.2"):new("ReAction") flickerstreak@7: local dewdrop = AceLibrary("Dewdrop-2.0") flickerstreak@7: local tablet = AceLibrary("Tablet-2.0") flickerstreak@10: local ReBound = AceLibrary("ReBound-1.0") flickerstreak@1: flickerstreak@7: -- private functions flickerstreak@2: local function tcopy(t) flickerstreak@2: local r = { } flickerstreak@2: for k, v in pairs(t) do flickerstreak@2: r[k] = (type(v) == "table" and tcopy(v) or v) flickerstreak@2: end flickerstreak@2: return r flickerstreak@2: end flickerstreak@2: flickerstreak@7: -- private constants flickerstreak@7: local EMPTY_BAR_SLOT = -1 flickerstreak@7: flickerstreak@7: -- key binding label constants flickerstreak@7: BINDING_HEADER_REACTION = L["ReAction"] flickerstreak@7: BINDING_NAME_REACTION_TOGGLELOCK = L["Toggle ReAction Bar Lock"] flickerstreak@10: BINDING_NAME_REACTION_TOGGLEKEYBIND = L["ReAction Keybinding Mode"] flickerstreak@7: flickerstreak@10: -- UI panel strings flickerstreak@10: REACTION_KEYBIND_TITLE = L["ReAction Keybinding"] flickerstreak@10: REACTION_KEYBIND_SUBTITLE = L["Click Buttons to Set Keybindings"] flickerstreak@10: REACTION_KEYBIND_DONE = L["Save"] flickerstreak@10: REACTION_KEYBIND_REVERT = L["Revert"] flickerstreak@7: flickerstreak@10: flickerstreak@10: flickerstreak@10: ------------------------------ flickerstreak@10: -- AceAddon setup flickerstreak@10: ------------------------------ flickerstreak@7: local main = AceLibrary("AceAddon-2.0"):new( flickerstreak@7: "AceConsole-2.0", flickerstreak@7: "AceEvent-2.0", flickerstreak@7: "AceDB-2.0", flickerstreak@7: "FuBarPlugin-2.0" flickerstreak@7: ) flickerstreak@1: flickerstreak@10: function main:OnInitialize() flickerstreak@10: self:RegisterChatCommand( {L["/reaction"], L["/rxn"]}, ReActionConsoleOptions, "REACTION" ) flickerstreak@10: self:RegisterDB("ReActionDB","ReActionDBPC") flickerstreak@10: self:RegisterDefaults("profile", ReAction_DefaultProfile) flickerstreak@10: self:RegisterEvent("PLAYER_REGEN_DISABLED","CombatLockdown") flickerstreak@10: self:RegisterEvent("PLAYER_ENTERING_WORLD","HideDefaultBars") flickerstreak@10: self:DisableDefaultKeybindings() flickerstreak@1: flickerstreak@10: -- initial non-persistent state flickerstreak@10: self.locked = true flickerstreak@10: self.bars = { } flickerstreak@10: end flickerstreak@7: flickerstreak@10: -- OnEnable is called at startup (startup = true, oldConfig = nil), flickerstreak@10: -- and when the profile is changed (startup = false, oldConfig ~= nil ) flickerstreak@10: function main:OnEnable( startup, oldConfig ) flickerstreak@10: if self.db.profile.firstRunDone ~= true then flickerstreak@10: self.db.profile.bars = tcopy(ReAction_DefaultBlizzardBars) flickerstreak@10: end flickerstreak@10: self:DestroyAllBars() flickerstreak@10: self:SetupBars() flickerstreak@10: self:UpgradeProfile() flickerstreak@10: self:SetupKeybindings( oldConfig and oldConfig.bindings ) flickerstreak@10: if self.db.profile.firstRunDone ~= true then flickerstreak@10: self:Unlock() flickerstreak@10: end flickerstreak@10: self.db.profile.firstRunDone = true flickerstreak@10: end flickerstreak@7: flickerstreak@10: function main:OnDisable() flickerstreak@10: self:Lock() flickerstreak@10: end flickerstreak@10: flickerstreak@10: -- OnProfileEnable() is only called when switching profiles, NOT for the initial profile at load time. flickerstreak@10: function main:OnProfileEnable( oldName, oldData ) flickerstreak@10: self:OnEnable(false, oldData) flickerstreak@10: end flickerstreak@10: flickerstreak@10: function main:UpgradeProfile() flickerstreak@10: if self.db.profile.firstRunDone ~= true and #self.db.profile.bindings == 0 then flickerstreak@10: for _, bar in pairs(self.bars) do flickerstreak@10: for _, button in pairs(bar.buttons) do flickerstreak@10: local key = ReBound:GetBinding(button:GetActionFrame(),"LeftButton") flickerstreak@10: if key and #key > 0 and not self.db.profile.bindings[key] then flickerstreak@10: self:REBOUND_BIND(key,button:GetActionFrame():GetName(),"LeftButton") flickerstreak@10: end flickerstreak@10: end flickerstreak@10: end flickerstreak@10: end flickerstreak@10: end flickerstreak@10: flickerstreak@10: flickerstreak@10: flickerstreak@10: flickerstreak@10: -------------------------------------------- flickerstreak@7: -- FuBar plugin setup flickerstreak@10: -- Even if FuBar isn't installed, the plugin flickerstreak@10: -- provides a nice minimap-button interface. flickerstreak@10: --------------------------------------------- flickerstreak@7: main.hasIcon = "Interface\\Icons\\INV_Qiraj_JewelEncased" flickerstreak@7: main.hasNoColor = true flickerstreak@7: main.hideMenuTitle = true flickerstreak@7: main.defaultPosition = "LEFT" flickerstreak@7: main.defaultMinimapPosition = 240 -- degrees flickerstreak@7: main.OnMenuRequest = tcopy(ReActionGlobalMenuOptions) -- use a copy, or bar menus will have FuBar inserted items flickerstreak@7: main.independentProfile = true flickerstreak@7: flickerstreak@7: -- set the handler for the global bar menu options flickerstreak@7: -- have to do this after tcopy() above, otherwise it will try to copy the handler object (bad idea) flickerstreak@7: ReActionGlobalMenuOptions.handler = main flickerstreak@7: flickerstreak@7: function main:OnTooltipUpdate() flickerstreak@7: local c = tablet:AddCategory("columns", 2) flickerstreak@7: c:AddLine("text", L["Bar lock"], "text2", self.locked and ("|cffff0000"..L["Locked"].."|r") or ("|cffffcc00"..L["Unlocked"].."|r")) flickerstreak@7: c:AddLine("text", L["Button lock"], "text2", LOCK_ACTIONBAR == "1" and ("|cffcc0000"..L["Locked"].."|r") or ("|cff00cc00"..L["Unlocked"].."|r")) flickerstreak@10: c:AddLine("text", L["Kebinding mode"], "text2", self:GetKeybindMode() and ("|cff33ff33"..L["On"].."|r") or ("|cffffcc00"..L["Off"].."|r")) flickerstreak@7: tablet:SetHint(L["|cffffcc00Shift-Click for bar lock|n|cff33ff33Alt-Click|r for keybindings|nRight-click for menu"]) flickerstreak@7: end flickerstreak@7: flickerstreak@7: function main:OnClick(button) flickerstreak@7: if IsShiftKeyDown() then flickerstreak@7: self:ToggleLocked() flickerstreak@7: self:UpdateDisplay() flickerstreak@7: elseif IsAltKeyDown() then flickerstreak@10: self:ToggleKeybindMode() flickerstreak@7: self:UpdateDisplay() flickerstreak@7: end flickerstreak@7: end flickerstreak@7: flickerstreak@7: flickerstreak@10: flickerstreak@10: flickerstreak@10: ------------------------------ flickerstreak@10: -- Key binding functions flickerstreak@10: ------------------------------ flickerstreak@10: function main:DisableDefaultKeybindings() flickerstreak@10: -- change the labels on all actionbar keybindings in the default flickerstreak@10: -- interface. flickerstreak@10: local label = "|cff999999("..L["Use ReAction"]..")|r" flickerstreak@10: for i = 1, 12 do flickerstreak@10: setglobal("BINDING_NAME_ACTIONBUTTON"..i,label) flickerstreak@10: for j = 1, 4 do flickerstreak@10: setglobal("BINDING_NAME_MULTIACTIONBAR"..j.."BUTTON"..i,label) flickerstreak@10: end flickerstreak@10: end flickerstreak@10: for i = 1, 6 do flickerstreak@10: setglobal("BINDING_NAME_ACTIONPAGE"..i,label) flickerstreak@10: end flickerstreak@10: for i = 1, 10 do flickerstreak@10: setglobal("BINDING_NAME_BONUSACTIONBUTTON"..i,label) flickerstreak@10: setglobal("BINDING_NAME_SHAPESHIFTBUTTON"..i,label) flickerstreak@10: end flickerstreak@10: BINDING_HEADER_ACTIONBAR = "|cff999999"..L["Action Bar Functions Disabled"].."|r" flickerstreak@10: BINDING_HEADER_MULTIACTIONBAR = "|cff999999"..L["Multi-Action Bar Functions Disabled"].."|r" flickerstreak@10: BINDING_NAME_NEXTACTIONPAGE = label flickerstreak@10: BINDING_NAME_PREVIOUSACTIONPAGE = label flickerstreak@10: end flickerstreak@10: flickerstreak@10: function main:SetupKeybindings( previous ) flickerstreak@10: if previous then flickerstreak@10: self:UnregisterEvent("REBOUND_BIND") flickerstreak@10: self:UnregisterEvent("REBOUND_UNBIND") flickerstreak@10: for key, binding in pairs(previous) do flickerstreak@10: ReBound:ClearBinding(key, getglobal(binding.target), binding.button, true) flickerstreak@10: end flickerstreak@10: end flickerstreak@10: if self.db.profile.firstRunDone ~= true then flickerstreak@10: self:StealKeyBindings() flickerstreak@10: else flickerstreak@10: for key, binding in pairs(self.db.profile.bindings) do flickerstreak@10: ReBound:SetBinding(key, getglobal(binding.target), binding.button) flickerstreak@10: end flickerstreak@10: end flickerstreak@10: SaveBindings(GetCurrentBindingSet()) flickerstreak@10: self:RegisterEvent("REBOUND_BIND") flickerstreak@10: self:RegisterEvent("REBOUND_UNBIND") flickerstreak@10: end flickerstreak@10: flickerstreak@10: function main:StealKeyBindings() flickerstreak@10: -- steal the keybindings of the main action bar and assign them to rebar 1, buttons 1-12 flickerstreak@10: for i = 1, 12 do flickerstreak@10: local key = GetBindingKey("ACTIONBUTTON"..i) flickerstreak@10: if key and #key > 0 then flickerstreak@10: ReBound:ClearBinding(key,nil,nil,true) -- suppress notification printouts flickerstreak@10: ReBound:SetBinding(key, self.bars[1].buttons[i]:GetActionFrame(), "LeftButton") flickerstreak@10: end flickerstreak@10: end flickerstreak@10: SaveBindings(GetCurrentBindingSet()) flickerstreak@10: end flickerstreak@10: flickerstreak@10: function main:REBOUND_BIND(key, target, button) flickerstreak@10: if key and target then flickerstreak@10: self.db.profile.bindings[key] = { target = target, button = button } flickerstreak@10: end flickerstreak@10: end flickerstreak@10: flickerstreak@10: function main:REBOUND_UNBIND(key) flickerstreak@10: if key then flickerstreak@10: self.db.profile.bindings[key] = nil flickerstreak@10: end flickerstreak@10: end flickerstreak@10: flickerstreak@10: function main:ToggleKeybindMode() flickerstreak@10: self:SetKeybindMode(not self:GetKeybindMode()) flickerstreak@10: end flickerstreak@10: flickerstreak@10: function main:GetKeybindMode() flickerstreak@10: return self.keybindMode flickerstreak@10: end flickerstreak@10: flickerstreak@10: function main:SetKeybindMode(enabled) flickerstreak@10: if not InCombatLockdown() then flickerstreak@10: self.keybindMode = enabled flickerstreak@10: for _, bar in pairs(self.bars) do flickerstreak@10: for __, button in pairs(bar.buttons) do flickerstreak@10: if button and button ~= EMPTY_BAR_SLOT then flickerstreak@10: button:TempShow(enabled) flickerstreak@10: end flickerstreak@10: end flickerstreak@10: end flickerstreak@10: if enabled then flickerstreak@10: ReBound:ShowAll() flickerstreak@10: ReActionKeybindDialog:Show() flickerstreak@10: else flickerstreak@10: ReBound:HideAll() flickerstreak@10: if ReActionKeybindDialog:IsShown() then flickerstreak@10: ReActionKeybindDialog:Hide() flickerstreak@10: end flickerstreak@10: end flickerstreak@10: else flickerstreak@10: UIErrorsFrame:AddMessage(ERROR_NOT_IN_COMBAT) flickerstreak@10: end flickerstreak@10: end flickerstreak@10: flickerstreak@10: flickerstreak@10: flickerstreak@10: flickerstreak@10: ---------------------------- flickerstreak@10: -- Bar lock/unlock functions flickerstreak@10: ---------------------------- flickerstreak@10: function main:CombatLockdown() flickerstreak@10: if not self:IsLocked() then flickerstreak@10: self:Lock() flickerstreak@10: UIErrorsFrame:AddMessage(L["ReAction bars locked when in combat"]) flickerstreak@10: end flickerstreak@10: ReActionKeybindDialog:Hide() flickerstreak@10: end flickerstreak@10: flickerstreak@7: function main:SetLocked( lock ) flickerstreak@2: if lock ~= self.locked then flickerstreak@2: if not lock and InCombatLockdown() then flickerstreak@10: UIErrorsFrame:AddMessage(ERROR_NOT_IN_COMBAT) flickerstreak@2: else flickerstreak@2: self.locked = lock and true or false -- force data integrity flickerstreak@2: for _, bar in pairs(self.bars) do flickerstreak@7: if bar ~= EMPTY_BAR_SLOT then flickerstreak@7: if self.locked then flickerstreak@7: bar:HideControls() flickerstreak@7: -- close any dewdrop menu owned by the bar flickerstreak@7: if bar:GetControlFrame() == dewdrop:GetOpenedParent() then flickerstreak@7: dewdrop:Close() flickerstreak@7: end flickerstreak@7: else flickerstreak@7: bar:ShowControls() flickerstreak@7: end flickerstreak@7: end flickerstreak@2: end flickerstreak@2: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@7: function main:IsLocked() flickerstreak@1: return self.locked flickerstreak@1: end flickerstreak@1: flickerstreak@7: function main:Lock() flickerstreak@1: self:SetLocked(true) flickerstreak@1: end flickerstreak@1: flickerstreak@7: function main:Unlock() flickerstreak@1: self:SetLocked(false) flickerstreak@1: end flickerstreak@1: flickerstreak@7: function main:ToggleLocked() flickerstreak@7: main:SetLocked( not(self.locked) ) flickerstreak@1: end flickerstreak@1: flickerstreak@1: flickerstreak@1: flickerstreak@10: -------------------------------------------------------- flickerstreak@10: -- Functions to hide the default Blizzard main bar parts flickerstreak@10: -------------------------------------------------------- flickerstreak@7: function main:HideArt() flickerstreak@1: if self.db.profile.hideArt then flickerstreak@7: -- the pet bar is a child of MainMenuBar, and can't be hidden. Need to reparent it flickerstreak@7: PetActionBarFrame:SetParent(UIParent) flickerstreak@1: MainMenuBar:Hide() -- this also hides the bags, xp bar, lag meter, and micro menu buttons. flickerstreak@7: -- these two are the pet bar background flickerstreak@7: -- unfortunately UIParent_ManageFramePositions() shows and hides these too flickerstreak@7: -- so they get reparented to MainMenuBar flickerstreak@7: SlidingActionBarTexture0:SetParent(MainMenuBar) flickerstreak@7: SlidingActionBarTexture1:SetParent(MainMenuBar) flickerstreak@1: else flickerstreak@7: SlidingActionBarTexture0:SetParent(PetActionBarFrame) flickerstreak@7: SlidingActionBarTexture1:SetParent(PetActionBarFrame) flickerstreak@1: MainMenuBar:Show() flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@7: function main:IsArtHidden() flickerstreak@1: return self.db.profile.hideArt flickerstreak@1: end flickerstreak@1: flickerstreak@7: function main:SetHideArt( hide ) flickerstreak@2: if InCombatLockdown() then flickerstreak@2: UIErrorsFrame:AddMessage(SPELL_FAILED_AFFECTING_COMBAT) flickerstreak@2: else flickerstreak@2: self.db.profile.hideArt = hide and true or false -- force data integrity flickerstreak@2: self:HideArt() flickerstreak@2: end flickerstreak@1: end flickerstreak@1: flickerstreak@7: function main:ToggleHideArt() flickerstreak@1: self:SetHideArt( not self:IsArtHidden() ) flickerstreak@1: end flickerstreak@1: flickerstreak@1: -- Hide default Blizzard bars flickerstreak@1: local blizzDefaultBars = { flickerstreak@1: ActionButton1, flickerstreak@1: ActionButton2, flickerstreak@1: ActionButton3, flickerstreak@1: ActionButton4, flickerstreak@1: ActionButton5, flickerstreak@1: ActionButton6, flickerstreak@1: ActionButton7, flickerstreak@1: ActionButton8, flickerstreak@1: ActionButton9, flickerstreak@1: ActionButton10, flickerstreak@1: ActionButton11, flickerstreak@1: ActionButton12, flickerstreak@7: PetActionButton1, flickerstreak@7: PetActionButton2, flickerstreak@7: PetActionButton3, flickerstreak@7: PetActionButton4, flickerstreak@7: PetActionButton5, flickerstreak@7: PetActionButton6, flickerstreak@7: PetActionButton7, flickerstreak@7: PetActionButton8, flickerstreak@7: PetActionButton9, flickerstreak@7: PetActionButton10, flickerstreak@7: -- NOT the PetActionBarFrame, though - we need that to auto-hide/show our pet action bars flickerstreak@7: MainMenuBarPageNumber, flickerstreak@7: ActionBarUpButton, flickerstreak@7: ActionBarDownButton, flickerstreak@1: BonusActionBarFrame, flickerstreak@7: ShapeshiftBarFrame, flickerstreak@1: MultiBarLeft, flickerstreak@1: MultiBarRight, flickerstreak@1: MultiBarBottomLeft, flickerstreak@7: MultiBarBottomRight, flickerstreak@1: } flickerstreak@1: flickerstreak@7: local function disableUIOptions() flickerstreak@7: -- disable the buttons to hide/show the blizzard multiaction bars flickerstreak@7: -- see UIOptionsFrame.lua and .xml flickerstreak@7: -- This is called every time the options panel is shown, after it is set up flickerstreak@7: for _, idx in pairs( { 33, 34, 35, 36, 37, 40 } ) do flickerstreak@7: local f = getglobal("UIOptionsFrameCheckButton"..idx) flickerstreak@7: f.disabled = true flickerstreak@7: OptionsFrame_DisableCheckBox(f) flickerstreak@7: f:SetChecked(false) flickerstreak@7: end flickerstreak@7: end flickerstreak@1: flickerstreak@7: function main:HideDefaultBars() flickerstreak@7: for _, f in pairs(blizzDefaultBars) do flickerstreak@7: f:Hide() flickerstreak@7: f:ClearAllPoints() flickerstreak@7: f:SetParent(ReAction.recycler) flickerstreak@7: f:SetPoint("TOPLEFT") flickerstreak@7: end flickerstreak@7: flickerstreak@7: MainMenuBar:SetFrameStrata("LOW") -- otherwise it appears on top of bars, if it isn't hidden flickerstreak@7: hooksecurefunc("UIOptionsFrame_Load",disableUIOptions) flickerstreak@7: end flickerstreak@7: flickerstreak@7: flickerstreak@10: flickerstreak@10: flickerstreak@10: --------------------------------------- flickerstreak@10: -- Bar setup and manipulation functions flickerstreak@10: --------------------------------------- flickerstreak@7: -- Reset bars to blizzard defaults flickerstreak@7: function main:ResetBars() flickerstreak@2: if InCombatLockdown() then flickerstreak@2: UIErrorsFrame:AddMessage(SPELL_FAILED_AFFECTING_COMBAT) flickerstreak@2: else flickerstreak@7: self:DestroyAllBars() flickerstreak@7: self.db.profile.bars = tcopy(ReAction_DefaultBlizzardBars) flickerstreak@2: self:SetupBars() flickerstreak@2: end flickerstreak@1: end flickerstreak@1: flickerstreak@7: function main:DestroyAllBars() flickerstreak@7: -- destroy any existing bars flickerstreak@7: for id = 1, table.maxn(self.bars) do flickerstreak@7: self:DestroyBar(id) flickerstreak@7: end flickerstreak@7: end flickerstreak@7: flickerstreak@7: function main:SetupBars() flickerstreak@1: -- hide the default Blizzard art, if configued flickerstreak@1: self:HideArt() flickerstreak@1: flickerstreak@1: -- set up the bars from the profile flickerstreak@2: -- note the use of table.maxn rather than # or ipairs: flickerstreak@2: -- our array of bars can in fact contain holes flickerstreak@2: for id = 1, table.maxn(self.db.profile.bars) do flickerstreak@2: local config = self.db.profile.bars[id] flickerstreak@2: if config then flickerstreak@7: self:CreateBar(config, id) flickerstreak@2: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: -- anchor the bars, have to do this in a second pass because flickerstreak@1: -- they might be anchored to each other in a non-ordered way flickerstreak@2: for _, bar in pairs(self.bars) do flickerstreak@7: if bar ~= EMPTY_BAR_SLOT then flickerstreak@7: bar:ApplyAnchor() flickerstreak@2: end flickerstreak@2: end flickerstreak@1: end flickerstreak@1: flickerstreak@7: function main:CreateBar( config, id ) flickerstreak@7: local bar = ReBar:new(config, id) flickerstreak@7: local buttonType = ReAction:GetButtonType(config.btnConfig.subtype) flickerstreak@1: flickerstreak@7: if buttonType then flickerstreak@7: self.bars[id] = bar flickerstreak@7: self.db.profile.bars[id] = config flickerstreak@7: flickerstreak@7: -- initialize dewdrop menu flickerstreak@7: local cf = bar:GetControlFrame() flickerstreak@7: dewdrop:Register(cf, flickerstreak@7: 'children', flickerstreak@7: function() flickerstreak@7: dewdrop:FeedAceOptionsTable(ReActionGlobalMenuOptions) flickerstreak@7: dewdrop:FeedAceOptionsTable(GenerateReActionBarOptions(bar,self)) flickerstreak@7: dewdrop:FeedAceOptionsTable(buttonType:GenerateOptionsTable(config.btnConfig, function() return bar:GetButtonList() end)) flickerstreak@7: end, flickerstreak@7: 'cursorX', true, flickerstreak@7: 'cursorY', true flickerstreak@7: ) flickerstreak@7: flickerstreak@7: bar:GetControlFrame():SetScript("OnClick", flickerstreak@7: function(btn) flickerstreak@7: if btn == "RightButton" then flickerstreak@7: dewdrop:Open(cf) flickerstreak@7: end flickerstreak@7: end flickerstreak@7: ) flickerstreak@7: flickerstreak@7: if not self.locked then flickerstreak@7: bar:ShowControls() flickerstreak@7: end flickerstreak@7: return bar flickerstreak@7: else flickerstreak@7: if bar then flickerstreak@7: bar:Destroy() flickerstreak@7: end flickerstreak@7: error(L["Tried to create a button of unknown type"]) flickerstreak@7: end flickerstreak@7: end flickerstreak@7: flickerstreak@7: function main:DestroyBar( id ) flickerstreak@7: local bar = self.bars[id] flickerstreak@7: if bar and bar ~= EMPTY_BAR_SLOT then flickerstreak@7: local cf = bar:GetControlFrame() flickerstreak@7: if cf == dewdrop:GetOpenedParent() then flickerstreak@7: dewdrop:Close() flickerstreak@7: dewdrop:Unregister(cf) flickerstreak@7: end flickerstreak@7: bar:Destroy() flickerstreak@7: -- we can't do tremove because each bar ID is encoded into the flickerstreak@7: -- frame names as they're created. Need a blank entry in the table. flickerstreak@7: -- The nice thing is that table.insert in NewBar() will automatically flickerstreak@7: -- find the lowest numbered nil slot. flickerstreak@7: self.bars[id] = EMPTY_BAR_SLOT flickerstreak@7: end flickerstreak@7: end flickerstreak@7: flickerstreak@10: -- flickerstreak@10: -- this function is a wrapper for CreateBar() which looks up the bar type flickerstreak@10: -- and constructs a new configuration object of the right type. flickerstreak@7: function main:NewBar( type ) flickerstreak@7: if InCombatLockdown() then flickerstreak@7: UIErrorsFrame:AddMessage(SPELL_FAILED_AFFECTING_COMBAT) flickerstreak@7: else flickerstreak@7: local t = ReAction:GetButtonType(type) flickerstreak@7: if t then flickerstreak@7: local c = tcopy(ReAction_DefaultBarConfig["ReAction"][type]) flickerstreak@7: local id = nil flickerstreak@7: for i = 1, table.maxn(self.bars) + 1 do -- there may be holes, so #self.bars won't work flickerstreak@7: if self.bars[i] == nil or self.bars[i] == EMPTY_BAR_SLOT then flickerstreak@7: id = i flickerstreak@7: break flickerstreak@7: end flickerstreak@7: end flickerstreak@7: local bar = self:CreateBar(c, id) flickerstreak@7: bar:ApplyAnchor() flickerstreak@7: self:Unlock() flickerstreak@7: end flickerstreak@7: end flickerstreak@7: end flickerstreak@7: flickerstreak@10: -- flickerstreak@10: -- This function is a wrapper for DestroyBar() which does in-combat flickerstreak@10: -- checking and updates the config. flickerstreak@7: function main:DeleteBar(id) flickerstreak@2: if InCombatLockdown() then flickerstreak@2: UIErrorsFrame:AddMessage(SPELL_FAILED_AFFECTING_COMBAT) flickerstreak@2: else flickerstreak@2: if self.bars[id] then flickerstreak@7: self:DestroyBar(id) flickerstreak@2: self.db.profile.bars[id] = nil flickerstreak@2: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@10: flickerstreak@10: flickerstreak@10: flickerstreak@10: ----------------- flickerstreak@10: -- General utility flickerstreak@10: ----------------- flickerstreak@7: function main:ToggleIds() flickerstreak@7: if self.showIds then flickerstreak@7: ReAction:HideAllIds() flickerstreak@1: else flickerstreak@7: ReAction:ShowAllIds() flickerstreak@1: end flickerstreak@7: self.showIds = not self.showIds flickerstreak@1: end flickerstreak@1: flickerstreak@7: function main:AreIdsVisible() flickerstreak@7: return self.showIds flickerstreak@1: end flickerstreak@1: flickerstreak@10: -- set a global variable for Bindings.xml flickerstreak@10: ReActionAddOn = main flickerstreak@1: flickerstreak@1: