1400 lines
46 KiB
Lua
1400 lines
46 KiB
Lua
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
|
local AB = E:GetModule('ActionBars')
|
|
|
|
local _G = _G
|
|
local next, unpack = next, unpack
|
|
local ipairs, pairs, select, strmatch = ipairs, pairs, select, strmatch
|
|
local format, gsub, strsplit, strfind = format, gsub, strsplit, strfind
|
|
|
|
local ClearOnBarHighlightMarks = ClearOnBarHighlightMarks
|
|
local ClearOverrideBindings = ClearOverrideBindings
|
|
local ClearPetActionHighlightMarks = ClearPetActionHighlightMarks
|
|
local CreateFrame = CreateFrame
|
|
local GetBindingKey = GetBindingKey
|
|
local GetOverrideBarIndex = GetOverrideBarIndex
|
|
local GetSpellBookItemInfo = GetSpellBookItemInfo
|
|
local GetVehicleBarIndex = GetVehicleBarIndex
|
|
local hooksecurefunc = hooksecurefunc
|
|
local InCombatLockdown = InCombatLockdown
|
|
local PetDismiss = PetDismiss
|
|
local RegisterStateDriver = RegisterStateDriver
|
|
local SecureHandlerSetFrameRef = SecureHandlerSetFrameRef
|
|
local SetClampedTextureRotation = SetClampedTextureRotation
|
|
local SetCVar = SetCVar
|
|
local SetModifiedClick = SetModifiedClick
|
|
local SetOverrideBindingClick = SetOverrideBindingClick
|
|
local UnitAffectingCombat = UnitAffectingCombat
|
|
local UnitCastingInfo = UnitCastingInfo
|
|
local UnitChannelInfo = UnitChannelInfo
|
|
local UnitExists = UnitExists
|
|
local UnitHealth = UnitHealth
|
|
local UnitHealthMax = UnitHealthMax
|
|
local UnregisterStateDriver = UnregisterStateDriver
|
|
local UpdateOnBarHighlightMarksByFlyout = UpdateOnBarHighlightMarksByFlyout
|
|
local UpdateOnBarHighlightMarksByPetAction = UpdateOnBarHighlightMarksByPetAction
|
|
local UpdateOnBarHighlightMarksBySpell = UpdateOnBarHighlightMarksBySpell
|
|
local UpdatePetActionHighlightMarks = UpdatePetActionHighlightMarks
|
|
local VehicleExit = VehicleExit
|
|
|
|
local SPELLS_PER_PAGE = SPELLS_PER_PAGE
|
|
local TOOLTIP_UPDATE_TIME = TOOLTIP_UPDATE_TIME
|
|
local NUM_ACTIONBAR_BUTTONS = NUM_ACTIONBAR_BUTTONS
|
|
local COOLDOWN_TYPE_LOSS_OF_CONTROL = COOLDOWN_TYPE_LOSS_OF_CONTROL
|
|
local C_PetBattles_IsInBattle = C_PetBattles.IsInBattle
|
|
|
|
local LAB = E.Libs.LAB
|
|
local LSM = E.Libs.LSM
|
|
local Masque = E.Masque
|
|
local MasqueGroup = Masque and Masque:Group('ElvUI', 'ActionBars')
|
|
|
|
local hiddenParent = CreateFrame('Frame', nil, _G.UIParent)
|
|
hiddenParent:SetAllPoints()
|
|
hiddenParent:Hide()
|
|
|
|
AB.RegisterCooldown = E.RegisterCooldown
|
|
AB.handledBars = {} --List of all bars
|
|
AB.handledbuttons = {} --List of all buttons that have been modified.
|
|
AB.barDefaults = {
|
|
bar1 = {
|
|
page = 1,
|
|
bindButtons = 'ACTIONBUTTON',
|
|
conditions = format('[overridebar] %d; [vehicleui] %d; [possessbar] %d; [shapeshift] 13; [form,noform] 0; [bar:2] 2; [bar:3] 3; [bar:4] 4; [bar:5] 5; [bar:6] 6;', GetOverrideBarIndex(), GetVehicleBarIndex(), GetVehicleBarIndex()),
|
|
position = 'BOTTOM,ElvUIParent,BOTTOM,-1,191',
|
|
},
|
|
bar2 = {
|
|
page = 5,
|
|
bindButtons = 'MULTIACTIONBAR2BUTTON',
|
|
conditions = '',
|
|
position = 'BOTTOM,ElvUIParent,BOTTOM,0,4',
|
|
},
|
|
bar3 = {
|
|
page = 6,
|
|
bindButtons = 'MULTIACTIONBAR1BUTTON',
|
|
conditions = '',
|
|
position = 'BOTTOM,ElvUIParent,BOTTOM,-1,139',
|
|
},
|
|
bar4 = {
|
|
page = 4,
|
|
bindButtons = 'MULTIACTIONBAR4BUTTON',
|
|
conditions = '',
|
|
position = 'RIGHT,ElvUIParent,RIGHT,-4,0',
|
|
},
|
|
bar5 = {
|
|
page = 3,
|
|
bindButtons = 'MULTIACTIONBAR3BUTTON',
|
|
conditions = '',
|
|
position = 'BOTTOM,ElvUIParent,BOTTOM,-92,57',
|
|
},
|
|
bar6 = {
|
|
page = 2,
|
|
bindButtons = 'ELVUIBAR6BUTTON',
|
|
conditions = '',
|
|
position = 'BOTTOM,ElvUI_Bar2,TOP,0,2',
|
|
},
|
|
bar7 = {
|
|
page = 7,
|
|
bindButtons = 'EXTRABAR7BUTTON',
|
|
conditions = '',
|
|
position = 'BOTTOM,ElvUI_Bar1,TOP,0,82',
|
|
},
|
|
bar8 = {
|
|
page = 8,
|
|
bindButtons = 'EXTRABAR8BUTTON',
|
|
conditions = '',
|
|
position = 'BOTTOM,ElvUI_Bar1,TOP,0,122',
|
|
},
|
|
bar9 = {
|
|
page = 9,
|
|
bindButtons = 'EXTRABAR9BUTTON',
|
|
conditions = '',
|
|
position = 'BOTTOM,ElvUI_Bar1,TOP,0,162',
|
|
},
|
|
bar10 = {
|
|
page = 10,
|
|
bindButtons = 'EXTRABAR10BUTTON',
|
|
conditions = '',
|
|
position = 'BOTTOM,ElvUI_Bar1,TOP,0,202',
|
|
},
|
|
}
|
|
|
|
AB.customExitButton = {
|
|
func = function()
|
|
if UnitExists('vehicle') then
|
|
VehicleExit()
|
|
else
|
|
PetDismiss()
|
|
end
|
|
end,
|
|
texture = [[Interface\Icons\Spell_Shadow_SacrificialShield]],
|
|
tooltip = _G.LEAVE_VEHICLE,
|
|
}
|
|
|
|
function AB:HandleBackdropMultiplier(bar, backdropSpacing, buttonSpacing, widthMult, heightMult, anchorUp, anchorLeft, horizontal, lastShownButton, anchorRowButton)
|
|
if not bar.backdrop:IsShown() then return end
|
|
|
|
local useWidthMult = widthMult > 1
|
|
local useHeightMult = heightMult > 1
|
|
if useWidthMult or useHeightMult then
|
|
local oldWidth, oldHeight = bar.backdrop:GetSize()
|
|
if useHeightMult then
|
|
local offset = ((oldHeight + buttonSpacing) * (heightMult - 1)) - backdropSpacing
|
|
local anchorPoint = anchorUp and 'TOP' or 'BOTTOM'
|
|
bar.backdrop:Point(anchorPoint, lastShownButton, anchorPoint, 0, anchorUp and offset or -offset)
|
|
end
|
|
if useWidthMult then
|
|
local offset = ((oldWidth + buttonSpacing) * (widthMult - 1)) - backdropSpacing
|
|
bar.backdrop:Point(horizontal, anchorRowButton, horizontal, anchorLeft and -offset or offset, 0)
|
|
end
|
|
end
|
|
end
|
|
|
|
function AB:HandleBackdropMover(bar, backdropSpacing)
|
|
local width, height = bar.backdrop:GetSize()
|
|
if not bar.backdrop:IsShown() then
|
|
local spacing = backdropSpacing * 2
|
|
bar:SetSize(width - spacing, height - spacing)
|
|
else
|
|
bar:SetSize(width, height)
|
|
end
|
|
end
|
|
|
|
function AB:HandleButton(bar, button, index, lastButton, lastColumnButton)
|
|
local db = bar.db
|
|
|
|
local numButtons = db.buttons
|
|
local buttonsPerRow = db.buttonsPerRow
|
|
local buttonWidth = (db.buttonsize or db.buttonSize)
|
|
local buttonHeight = db.keepSizeRatio and (db.buttonsize or db.buttonSize * 1.4) or db.buttonHeight
|
|
|
|
if bar.LastButton then
|
|
if numButtons > bar.LastButton then numButtons = bar.LastButton end
|
|
if buttonsPerRow > bar.LastButton then buttonsPerRow = bar.LastButton end
|
|
end
|
|
|
|
if numButtons < buttonsPerRow then buttonsPerRow = numButtons end
|
|
|
|
local _, horizontal, anchorUp, anchorLeft = AB:GetGrowth(db.point)
|
|
local point, relativeFrame, relativePoint, x, y
|
|
if index == 1 then
|
|
local firstButtonSpacing = db.backdrop and (E.Border + db.backdropSpacing) or E.Spacing
|
|
if db.point == 'BOTTOMLEFT' then
|
|
x, y = firstButtonSpacing, firstButtonSpacing
|
|
elseif db.point == 'TOPRIGHT' then
|
|
x, y = -firstButtonSpacing, -firstButtonSpacing
|
|
elseif db.point == 'TOPLEFT' then
|
|
x, y = firstButtonSpacing, -firstButtonSpacing
|
|
else
|
|
x, y = -firstButtonSpacing, firstButtonSpacing
|
|
end
|
|
|
|
point, relativeFrame, relativePoint = db.point, bar, db.point
|
|
elseif (index - 1) % buttonsPerRow == 0 then
|
|
point, relativeFrame, relativePoint, x, y = 'TOP', lastColumnButton, 'BOTTOM', 0, -(db.buttonspacing or db.buttonSpacing)
|
|
if anchorUp then
|
|
point, relativePoint, y = 'BOTTOM', 'TOP', (db.buttonspacing or db.buttonSpacing)
|
|
end
|
|
else
|
|
point, relativeFrame, relativePoint, x, y = 'LEFT', lastButton, 'RIGHT', (db.buttonspacing or db.buttonSpacing), 0
|
|
if anchorLeft then
|
|
point, relativePoint, x = 'RIGHT', 'LEFT', -(db.buttonspacing or db.buttonSpacing)
|
|
end
|
|
end
|
|
|
|
button:SetParent(bar)
|
|
button:ClearAllPoints()
|
|
button:SetAttribute('showgrid', 1)
|
|
button:EnableMouse(not db.clickThrough)
|
|
button:Size(buttonWidth, buttonHeight)
|
|
button:Point(point, relativeFrame, relativePoint, x, y)
|
|
|
|
if index == 1 then
|
|
bar.backdrop:Point(point, button, point, anchorLeft and db.backdropSpacing or -db.backdropSpacing, anchorUp and -db.backdropSpacing or db.backdropSpacing)
|
|
elseif index == buttonsPerRow then
|
|
bar.backdrop:Point(horizontal, button, horizontal, anchorLeft and -db.backdropSpacing or db.backdropSpacing, 0)
|
|
end
|
|
|
|
if button.handleBackdrop then
|
|
local anchorPoint = anchorUp and 'TOP' or 'BOTTOM'
|
|
bar.backdrop:Point(anchorPoint, button, anchorPoint, 0, anchorUp and db.backdropSpacing or -db.backdropSpacing)
|
|
end
|
|
end
|
|
|
|
function AB:TrimIcon(button, masque)
|
|
if not button.icon then return end
|
|
|
|
local left, right, top, bottom = unpack(button.db and button.db.customCoords or E.TexCoords)
|
|
local changeRatio = button.db and not button.db.keepSizeRatio
|
|
if changeRatio then
|
|
local width, height = button:GetSize()
|
|
local ratio = width / height
|
|
if ratio > 1 then
|
|
local trimAmount = (1 - (1 / ratio)) / 2
|
|
top = top + trimAmount
|
|
bottom = bottom - trimAmount
|
|
else
|
|
local trimAmount = (1 - ratio) / 2
|
|
left = left + trimAmount
|
|
right = right - trimAmount
|
|
end
|
|
end
|
|
|
|
-- always when masque is off, otherwise only when keepSizeRatio is off
|
|
if not masque or changeRatio then
|
|
button.icon:SetTexCoord(left, right, top, bottom)
|
|
end
|
|
end
|
|
|
|
function AB:GetGrowth(point)
|
|
local vertical = (point == 'TOPLEFT' or point == 'TOPRIGHT') and 'DOWN' or 'UP'
|
|
local horizontal = (point == 'BOTTOMLEFT' or point == 'TOPLEFT') and 'RIGHT' or 'LEFT'
|
|
local anchorUp, anchorLeft = vertical == 'UP', horizontal == 'LEFT'
|
|
|
|
return vertical, horizontal, anchorUp, anchorLeft
|
|
end
|
|
|
|
function AB:MoverMagic(bar) -- ~Simpy
|
|
local _, _, anchorUp, anchorLeft = AB:GetGrowth(bar.db.point)
|
|
|
|
bar:ClearAllPoints()
|
|
if not bar.backdrop:IsShown() then
|
|
bar:SetPoint('BOTTOMLEFT', bar.mover)
|
|
elseif anchorUp then
|
|
bar:SetPoint('BOTTOMLEFT', bar.mover, 'BOTTOMLEFT', anchorLeft and E.Border or -E.Border, -E.Border)
|
|
else
|
|
bar:SetPoint('TOPLEFT', bar.mover, 'TOPLEFT', anchorLeft and E.Border or -E.Border, E.Border)
|
|
end
|
|
end
|
|
|
|
function AB:PositionAndSizeBar(barName)
|
|
local db = AB.db[barName]
|
|
local bar = AB.handledBars[barName]
|
|
|
|
local buttonSpacing = db.buttonspacing
|
|
local backdropSpacing = db.backdropSpacing
|
|
local buttonsPerRow = db.buttonsPerRow
|
|
local numButtons = db.buttons
|
|
local point = db.point
|
|
local visibility = db.visibility
|
|
|
|
bar.db = db
|
|
bar.mouseover = db.mouseover
|
|
|
|
if numButtons < buttonsPerRow then buttonsPerRow = numButtons end
|
|
|
|
bar:SetParent(db.inheritGlobalFade and AB.fadeParent or E.UIParent)
|
|
bar:EnableMouse(not db.clickThrough)
|
|
bar:SetAlpha(bar.mouseover and 0 or db.alpha)
|
|
AB:FadeBarBlings(bar, bar.mouseover and 0 or db.alpha)
|
|
|
|
bar.backdrop:SetShown(db.backdrop)
|
|
bar.backdrop:ClearAllPoints()
|
|
|
|
AB:MoverMagic(bar)
|
|
|
|
local _, horizontal, anchorUp, anchorLeft = AB:GetGrowth(point)
|
|
local button, lastButton, lastColumnButton, anchorRowButton, lastShownButton
|
|
|
|
for i = 1, NUM_ACTIONBAR_BUTTONS do
|
|
lastButton = bar.buttons[i-1]
|
|
lastColumnButton = bar.buttons[i-buttonsPerRow]
|
|
button = bar.buttons[i]
|
|
button.db = db
|
|
|
|
if i == 1 or i == buttonsPerRow then
|
|
anchorRowButton = button
|
|
end
|
|
|
|
if i > numButtons then
|
|
button:Hide()
|
|
button.handleBackdrop = nil
|
|
else
|
|
button:Show()
|
|
button.handleBackdrop = true -- keep over HandleButton
|
|
lastShownButton = button
|
|
end
|
|
|
|
AB:HandleButton(bar, button, i, lastButton, lastColumnButton)
|
|
AB:StyleButton(button, nil, MasqueGroup and E.private.actionbar.masque.actionbars)
|
|
end
|
|
|
|
AB:HandleBackdropMultiplier(bar, backdropSpacing, buttonSpacing, db.widthMult, db.heightMult, anchorUp, anchorLeft, horizontal, lastShownButton, anchorRowButton)
|
|
AB:HandleBackdropMover(bar, backdropSpacing)
|
|
|
|
-- paging needs to be updated even if the bar is disabled
|
|
local defaults = AB.barDefaults[barName]
|
|
local page = AB:GetPage(barName, defaults.page, defaults.conditions)
|
|
RegisterStateDriver(bar, 'page', page)
|
|
bar:SetAttribute('page', page)
|
|
|
|
if not bar.initialized then
|
|
bar.initialized = true
|
|
|
|
if defaults.conditions:find('[form,noform]') then
|
|
bar:SetAttribute('newCondition', gsub(defaults.conditions, ' %[form,noform%] 0; ', ''))
|
|
bar:SetAttribute('hasTempBar', true)
|
|
else
|
|
bar:SetAttribute('hasTempBar', false)
|
|
end
|
|
end
|
|
|
|
if db.enabled or not bar.initialized then
|
|
visibility = gsub(visibility, '[\n\r]','')
|
|
|
|
E:EnableMover(bar.mover:GetName())
|
|
RegisterStateDriver(bar, 'visibility', visibility)
|
|
bar:Show()
|
|
else
|
|
E:DisableMover(bar.mover:GetName())
|
|
UnregisterStateDriver(bar, 'visibility')
|
|
bar:Hide()
|
|
end
|
|
|
|
E:SetMoverSnapOffset('ElvAB_'..bar.id, db.buttonspacing / 2)
|
|
|
|
if MasqueGroup and E.private.actionbar.masque.actionbars then
|
|
MasqueGroup:ReSkin()
|
|
|
|
-- masque retrims them all so we have to too
|
|
for btn in pairs(AB.handledbuttons) do
|
|
AB:TrimIcon(btn, true)
|
|
end
|
|
end
|
|
end
|
|
|
|
function AB:CreateBar(id)
|
|
local bar = CreateFrame('Frame', 'ElvUI_Bar'..id, E.UIParent, 'SecureHandlerStateTemplate')
|
|
SecureHandlerSetFrameRef(bar, 'MainMenuBarArtFrame', _G.MainMenuBarArtFrame)
|
|
|
|
local defaults = AB.barDefaults['bar'..id]
|
|
local point, anchor, attachTo, x, y = strsplit(',', defaults.position)
|
|
bar:Point(point, anchor, attachTo, x, y)
|
|
bar:SetFrameStrata('LOW')
|
|
bar.id = id
|
|
|
|
bar:CreateBackdrop(AB.db.transparent and 'Transparent')
|
|
bar.backdrop:SetFrameLevel(0)
|
|
|
|
bar.buttons = {}
|
|
bar.bindButtons = defaults.bindButtons
|
|
AB:HookScript(bar, 'OnEnter', 'Bar_OnEnter')
|
|
AB:HookScript(bar, 'OnLeave', 'Bar_OnLeave')
|
|
|
|
for i = 1, 12 do
|
|
bar.buttons[i] = LAB:CreateButton(i, format(bar:GetName()..'Button%d', i), bar, nil)
|
|
bar.buttons[i]:SetState(0, 'action', i)
|
|
|
|
for k = 1, 14 do
|
|
bar.buttons[i]:SetState(k, 'action', (k - 1) * 12 + i)
|
|
end
|
|
|
|
if i == 12 then
|
|
bar.buttons[i]:SetState(12, 'custom', AB.customExitButton)
|
|
end
|
|
|
|
if MasqueGroup and E.private.actionbar.masque.actionbars then
|
|
bar.buttons[i]:AddToMasque(MasqueGroup)
|
|
end
|
|
|
|
AB:HookScript(bar.buttons[i], 'OnEnter', 'Button_OnEnter')
|
|
AB:HookScript(bar.buttons[i], 'OnLeave', 'Button_OnLeave')
|
|
end
|
|
AB:UpdateButtonConfig(bar, bar.bindButtons)
|
|
|
|
if defaults.conditions:find('[form]') then
|
|
bar:SetAttribute('hasTempBar', true)
|
|
else
|
|
bar:SetAttribute('hasTempBar', false)
|
|
end
|
|
|
|
bar:SetAttribute('_onstate-page', [[
|
|
if HasTempShapeshiftActionBar() and self:GetAttribute('hasTempBar') then
|
|
newstate = GetTempShapeshiftBarIndex() or newstate
|
|
end
|
|
|
|
if newstate ~= 0 then
|
|
self:SetAttribute('state', newstate)
|
|
control:ChildUpdate('state', newstate)
|
|
self:GetFrameRef('MainMenuBarArtFrame'):SetAttribute('actionpage', newstate) --Update MainMenuBarArtFrame too. See issue #1848
|
|
else
|
|
local newCondition = self:GetAttribute('newCondition')
|
|
if newCondition then
|
|
newstate = SecureCmdOptionParse(newCondition)
|
|
self:SetAttribute('state', newstate)
|
|
control:ChildUpdate('state', newstate)
|
|
self:GetFrameRef('MainMenuBarArtFrame'):SetAttribute('actionpage', newstate)
|
|
end
|
|
end
|
|
]])
|
|
|
|
AB.handledBars['bar'..id] = bar
|
|
E:CreateMover(bar, 'ElvAB_'..id, L["Bar "]..id, nil, nil, nil,'ALL,ACTIONBARS',nil,'actionbar,playerBars,bar'..id)
|
|
|
|
return bar
|
|
end
|
|
|
|
function AB:PLAYER_REGEN_ENABLED()
|
|
if AB.NeedsUpdateButtonSettings then
|
|
AB:UpdateButtonSettings()
|
|
AB.NeedsUpdateButtonSettings = nil
|
|
end
|
|
if AB.NeedsUpdateMicroBarVisibility then
|
|
AB:UpdateMicroBarVisibility()
|
|
AB.NeedsUpdateMicroBarVisibility = nil
|
|
end
|
|
if AB.NeedsAdjustMaxStanceButtons then
|
|
AB:AdjustMaxStanceButtons(AB.NeedsAdjustMaxStanceButtons) --sometimes it holds the event, otherwise true. pass it before we nil it.
|
|
AB.NeedsAdjustMaxStanceButtons = nil
|
|
end
|
|
|
|
AB:UnregisterEvent('PLAYER_REGEN_ENABLED')
|
|
end
|
|
|
|
function AB:CreateVehicleLeave()
|
|
local db = E.db.actionbar.vehicleExitButton
|
|
if not db.enable then return end
|
|
|
|
local holder = CreateFrame('Frame', 'VehicleLeaveButtonHolder', E.UIParent)
|
|
holder:Point('BOTTOM', E.UIParent, 'BOTTOM', 0, 300)
|
|
holder:Size(_G.MainMenuBarVehicleLeaveButton:GetSize())
|
|
E:CreateMover(holder, 'VehicleLeaveButton', L["VehicleLeaveButton"], nil, nil, nil, 'ALL,ACTIONBARS', nil, 'actionbar,vehicleExitButton')
|
|
|
|
local Button = _G.MainMenuBarVehicleLeaveButton
|
|
Button:ClearAllPoints()
|
|
Button:SetParent(_G.UIParent)
|
|
Button:Point('CENTER', holder, 'CENTER')
|
|
|
|
if MasqueGroup and E.private.actionbar.masque.actionbars then
|
|
Button:StyleButton(true, true, true)
|
|
else
|
|
Button:CreateBackdrop(nil, true)
|
|
Button:GetNormalTexture():SetTexCoord(0.140625 + .08, 0.859375 - .06, 0.140625 + .08, 0.859375 - .08)
|
|
Button:GetPushedTexture():SetTexCoord(0.140625, 0.859375, 0.140625, 0.859375)
|
|
Button:StyleButton(nil, true, true)
|
|
end
|
|
|
|
hooksecurefunc(Button, 'SetPoint', function(_, _, parent)
|
|
if parent ~= holder then
|
|
Button:ClearAllPoints()
|
|
Button:SetParent(_G.UIParent)
|
|
Button:Point('CENTER', holder, 'CENTER')
|
|
end
|
|
end)
|
|
|
|
hooksecurefunc(Button, 'SetHighlightTexture', function(btn, tex)
|
|
if tex ~= btn.hover then
|
|
Button:SetHighlightTexture(btn.hover)
|
|
end
|
|
end)
|
|
|
|
AB:UpdateVehicleLeave()
|
|
end
|
|
|
|
function AB:UpdateVehicleLeave()
|
|
local db = E.db.actionbar.vehicleExitButton
|
|
_G.MainMenuBarVehicleLeaveButton:Size(db.size)
|
|
_G.MainMenuBarVehicleLeaveButton:SetFrameStrata(db.strata)
|
|
_G.MainMenuBarVehicleLeaveButton:SetFrameLevel(db.level)
|
|
_G.VehicleLeaveButtonHolder:Size(db.size)
|
|
end
|
|
|
|
function AB:ReassignBindings(event)
|
|
if event == 'UPDATE_BINDINGS' then
|
|
AB:UpdatePetBindings()
|
|
AB:UpdateStanceBindings()
|
|
AB:UpdateExtraBindings()
|
|
end
|
|
|
|
AB:UnregisterEvent('PLAYER_REGEN_DISABLED')
|
|
|
|
if InCombatLockdown() then return end
|
|
|
|
for _, bar in pairs(AB.handledBars) do
|
|
if bar then
|
|
ClearOverrideBindings(bar)
|
|
|
|
for _, button in ipairs(bar.buttons) do
|
|
if button.keyBoundTarget then
|
|
for k=1, select('#', GetBindingKey(button.keyBoundTarget)) do
|
|
local key = select(k, GetBindingKey(button.keyBoundTarget))
|
|
if key and key ~= '' then
|
|
SetOverrideBindingClick(bar, false, key, button:GetName())
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function AB:RemoveBindings()
|
|
if InCombatLockdown() then return end
|
|
|
|
for _, bar in pairs(AB.handledBars) do
|
|
if bar then
|
|
ClearOverrideBindings(bar)
|
|
end
|
|
end
|
|
|
|
AB:RegisterEvent('PLAYER_REGEN_DISABLED', 'ReassignBindings')
|
|
end
|
|
|
|
function AB:UpdateBar1Paging()
|
|
if AB.db.bar6.enabled then
|
|
AB.barDefaults.bar1.conditions = format('[possessbar] %d; [overridebar] %d; [shapeshift] 13; [form,noform] 0; [bar:3] 3; [bar:4] 4; [bar:5] 5; [bar:6] 6;', GetVehicleBarIndex(), GetOverrideBarIndex())
|
|
else
|
|
AB.barDefaults.bar1.conditions = format('[possessbar] %d; [overridebar] %d; [shapeshift] 13; [form,noform] 0; [bar:2] 2; [bar:3] 3; [bar:4] 4; [bar:5] 5; [bar:6] 6;', GetVehicleBarIndex(), GetOverrideBarIndex())
|
|
end
|
|
end
|
|
|
|
function AB:UpdateButtonSettingsForBar(barName)
|
|
local bar = AB.handledBars[barName]
|
|
AB:UpdateButtonConfig(bar, bar.bindButtons)
|
|
end
|
|
|
|
function AB:UpdateButtonSettings()
|
|
if not E.private.actionbar.enable then return end
|
|
|
|
if InCombatLockdown() then
|
|
AB.NeedsUpdateButtonSettings = true
|
|
AB:RegisterEvent('PLAYER_REGEN_ENABLED')
|
|
return
|
|
end
|
|
|
|
for barName, bar in pairs(AB.handledBars) do
|
|
if bar then
|
|
AB:UpdateButtonConfig(bar, bar.bindButtons) -- config them first
|
|
AB:PositionAndSizeBar(barName) -- db is set here, button style also runs here
|
|
end
|
|
end
|
|
|
|
for button in pairs(AB.handledbuttons) do
|
|
if button then
|
|
AB:StyleFlyout(button)
|
|
else
|
|
AB.handledbuttons[button] = nil
|
|
end
|
|
end
|
|
|
|
-- we can safely toggle these events when we arent using the handle overlay
|
|
if AB.db.handleOverlay then
|
|
LAB.eventFrame:RegisterEvent('SPELL_ACTIVATION_OVERLAY_GLOW_SHOW')
|
|
LAB.eventFrame:RegisterEvent('SPELL_ACTIVATION_OVERLAY_GLOW_HIDE')
|
|
else
|
|
LAB.eventFrame:UnregisterEvent('SPELL_ACTIVATION_OVERLAY_GLOW_SHOW')
|
|
LAB.eventFrame:UnregisterEvent('SPELL_ACTIVATION_OVERLAY_GLOW_HIDE')
|
|
end
|
|
|
|
AB:AdjustMaxStanceButtons()
|
|
AB:PositionAndSizeBarPet()
|
|
AB:PositionAndSizeBarShapeShift()
|
|
|
|
AB:UpdatePetBindings()
|
|
AB:UpdateStanceBindings() -- call after AdjustMaxStanceButtons
|
|
AB:UpdateFlyoutButtons()
|
|
end
|
|
|
|
function AB:GetPage(bar, defaultPage, condition)
|
|
local page = AB.db[bar].paging[E.myclass]
|
|
if not condition then condition = '' end
|
|
if not page then
|
|
page = ''
|
|
elseif page:match('[\n\r]') then
|
|
page = page:gsub('[\n\r]','')
|
|
end
|
|
|
|
if page then
|
|
condition = condition..' '..page
|
|
end
|
|
condition = condition..' '..defaultPage
|
|
|
|
return condition
|
|
end
|
|
|
|
function AB:StyleButton(button, noBackdrop, useMasque, ignoreNormal)
|
|
local name = button:GetName()
|
|
local macroText = _G[name..'Name']
|
|
local icon = _G[name..'Icon']
|
|
local shine = _G[name..'Shine']
|
|
local count = _G[name..'Count']
|
|
local flash = _G[name..'Flash']
|
|
local hotkey = _G[name..'HotKey']
|
|
local border = _G[name..'Border']
|
|
local normal = _G[name..'NormalTexture']
|
|
local normal2 = button:GetNormalTexture()
|
|
|
|
local db = button:GetParent().db
|
|
local color = AB.db.fontColor
|
|
local countPosition = AB.db.countTextPosition or 'BOTTOMRIGHT'
|
|
local countXOffset = AB.db.countTextXOffset or 0
|
|
local countYOffset = AB.db.countTextYOffset or 2
|
|
|
|
button.noBackdrop = noBackdrop
|
|
button.useMasque = useMasque
|
|
button.ignoreNormal = ignoreNormal
|
|
|
|
if normal and not ignoreNormal then normal:SetTexture(); normal:Hide(); normal:SetAlpha(0) end
|
|
if normal2 then normal2:SetTexture(); normal2:Hide(); normal2:SetAlpha(0) end
|
|
if border and not button.useMasque then border:Kill() end
|
|
|
|
if count then
|
|
count:ClearAllPoints()
|
|
|
|
if db and db.customCountFont then
|
|
count:Point(db.countTextPosition, db.countTextXOffset, db.countTextYOffset)
|
|
count:FontTemplate(LSM:Fetch('font', db.countFont), db.countFontSize, db.countFontOutline)
|
|
else
|
|
count:Point(countPosition, countXOffset, countYOffset)
|
|
count:FontTemplate(LSM:Fetch('font', AB.db.font), AB.db.fontSize, AB.db.fontOutline)
|
|
end
|
|
|
|
count:SetTextColor(color.r, color.g, color.b)
|
|
end
|
|
|
|
if macroText then
|
|
macroText:ClearAllPoints()
|
|
macroText:Point('BOTTOM', 0, 1)
|
|
macroText:FontTemplate(LSM:Fetch('font', AB.db.font), AB.db.fontSize, AB.db.fontOutline)
|
|
macroText:SetTextColor(color.r, color.g, color.b)
|
|
end
|
|
|
|
if not button.noBackdrop and not button.backdrop and not button.useMasque then
|
|
button:CreateBackdrop(AB.db.transparent and 'Transparent', true)
|
|
button.backdrop:SetAllPoints()
|
|
end
|
|
|
|
if flash then
|
|
if AB.db.flashAnimation then
|
|
flash:SetColorTexture(1.0, 0.2, 0.2, 0.45)
|
|
flash:ClearAllPoints()
|
|
flash:SetOutside(icon, 2, 2)
|
|
flash:SetDrawLayer('BACKGROUND', -1)
|
|
else
|
|
flash:SetTexture()
|
|
end
|
|
end
|
|
|
|
if icon and not useMasque then
|
|
AB:TrimIcon(button)
|
|
icon:SetInside()
|
|
end
|
|
|
|
if shine then
|
|
shine:SetAllPoints()
|
|
end
|
|
|
|
if button.SpellHighlightTexture then
|
|
button.SpellHighlightTexture:SetColorTexture(1, 1, 0, 0.45)
|
|
button.SpellHighlightTexture:SetAllPoints()
|
|
end
|
|
|
|
if AB.db.hotkeytext or AB.db.useRangeColorText then
|
|
if db and db.customHotkeyFont then
|
|
hotkey:FontTemplate(LSM:Fetch('font', db.hotkeyFont), db.hotkeyFontSize, db.hotkeyFontOutline)
|
|
else
|
|
hotkey:FontTemplate(LSM:Fetch('font', AB.db.font), AB.db.fontSize, AB.db.fontOutline)
|
|
end
|
|
|
|
if button.config and (button.config.outOfRangeColoring ~= 'hotkey') then
|
|
button.HotKey:SetTextColor(color.r, color.g, color.b)
|
|
end
|
|
end
|
|
|
|
--Extra Action Button
|
|
if button.style then
|
|
button.style:SetDrawLayer('BACKGROUND', -7)
|
|
end
|
|
|
|
button.FlyoutUpdateFunc = AB.StyleFlyout
|
|
AB:FixKeybindText(button)
|
|
|
|
if not button.useMasque then
|
|
button:StyleButton()
|
|
else
|
|
button:StyleButton(true, true, true)
|
|
end
|
|
|
|
if not AB.handledbuttons[button] then
|
|
button.cooldown.CooldownOverride = 'actionbar'
|
|
|
|
E:RegisterCooldown(button.cooldown)
|
|
|
|
AB.handledbuttons[button] = true
|
|
end
|
|
end
|
|
|
|
function AB:ColorSwipeTexture(cooldown)
|
|
if not cooldown then return end
|
|
|
|
local color = (cooldown.currentCooldownType == COOLDOWN_TYPE_LOSS_OF_CONTROL and AB.db.colorSwipeLOC) or AB.db.colorSwipeNormal
|
|
cooldown:SetSwipeColor(color.r, color.g, color.b, color.a)
|
|
end
|
|
|
|
function AB:FadeBlingTexture(cooldown, alpha)
|
|
if not cooldown then return end
|
|
cooldown:SetBlingTexture(alpha > 0.5 and 131010 or [[Interface\AddOns\ElvUI\Media\Textures\Blank]]) -- interface/cooldown/star4.blp
|
|
end
|
|
|
|
function AB:FadeBlings(alpha)
|
|
if AB.db.hideCooldownBling then return end
|
|
|
|
for i = 1, AB.fadeParent:GetNumChildren() do
|
|
local bar = select(i, AB.fadeParent:GetChildren())
|
|
if bar.buttons then
|
|
for _, button in ipairs(bar.buttons) do
|
|
AB:FadeBlingTexture(button.cooldown, alpha)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function AB:FadeBarBlings(bar, alpha)
|
|
if AB.db.hideCooldownBling then return end
|
|
|
|
for _, button in ipairs(bar.buttons) do
|
|
AB:FadeBlingTexture(button.cooldown, alpha)
|
|
end
|
|
end
|
|
|
|
function AB:Bar_OnEnter(bar)
|
|
if bar:GetParent() == AB.fadeParent and not AB.fadeParent.mouseLock then
|
|
E:UIFrameFadeIn(AB.fadeParent, 0.2, AB.fadeParent:GetAlpha(), 1)
|
|
AB:FadeBlings(1)
|
|
end
|
|
|
|
if bar.mouseover then
|
|
E:UIFrameFadeIn(bar, 0.2, bar:GetAlpha(), bar.db.alpha)
|
|
AB:FadeBarBlings(bar, bar.db.alpha)
|
|
end
|
|
end
|
|
|
|
function AB:Bar_OnLeave(bar)
|
|
if bar:GetParent() == AB.fadeParent and not AB.fadeParent.mouseLock then
|
|
local a = 1 - AB.db.globalFadeAlpha
|
|
E:UIFrameFadeOut(AB.fadeParent, 0.2, AB.fadeParent:GetAlpha(), a)
|
|
AB:FadeBlings(a)
|
|
end
|
|
|
|
if bar.mouseover then
|
|
E:UIFrameFadeOut(bar, 0.2, bar:GetAlpha(), 0)
|
|
AB:FadeBarBlings(bar, 0)
|
|
end
|
|
end
|
|
|
|
function AB:Button_OnEnter(button)
|
|
local bar = button:GetParent()
|
|
if bar:GetParent() == AB.fadeParent and not AB.fadeParent.mouseLock then
|
|
E:UIFrameFadeIn(AB.fadeParent, 0.2, AB.fadeParent:GetAlpha(), 1)
|
|
AB:FadeBlings(1)
|
|
end
|
|
|
|
if bar.mouseover then
|
|
E:UIFrameFadeIn(bar, 0.2, bar:GetAlpha(), bar.db.alpha)
|
|
AB:FadeBarBlings(bar, bar.db.alpha)
|
|
end
|
|
end
|
|
|
|
function AB:Button_OnLeave(button)
|
|
local bar = button:GetParent()
|
|
if bar:GetParent() == AB.fadeParent and not AB.fadeParent.mouseLock then
|
|
local a = 1 - AB.db.globalFadeAlpha
|
|
E:UIFrameFadeOut(AB.fadeParent, 0.2, AB.fadeParent:GetAlpha(), a)
|
|
AB:FadeBlings(a)
|
|
end
|
|
|
|
if bar.mouseover then
|
|
E:UIFrameFadeOut(bar, 0.2, bar:GetAlpha(), 0)
|
|
AB:FadeBarBlings(bar, 0)
|
|
end
|
|
end
|
|
|
|
function AB:BlizzardOptionsPanel_OnEvent()
|
|
_G.InterfaceOptionsActionBarsPanelBottomRight.Text:SetFormattedText(L["Remove Bar %d Action Page"], 2)
|
|
_G.InterfaceOptionsActionBarsPanelBottomLeft.Text:SetFormattedText(L["Remove Bar %d Action Page"], 3)
|
|
_G.InterfaceOptionsActionBarsPanelRightTwo.Text:SetFormattedText(L["Remove Bar %d Action Page"], 4)
|
|
_G.InterfaceOptionsActionBarsPanelRight.Text:SetFormattedText(L["Remove Bar %d Action Page"], 5)
|
|
|
|
_G.InterfaceOptionsActionBarsPanelBottomRight:SetScript('OnEnter', nil)
|
|
_G.InterfaceOptionsActionBarsPanelBottomLeft:SetScript('OnEnter', nil)
|
|
_G.InterfaceOptionsActionBarsPanelRightTwo:SetScript('OnEnter', nil)
|
|
_G.InterfaceOptionsActionBarsPanelRight:SetScript('OnEnter', nil)
|
|
end
|
|
|
|
function AB:FadeParent_OnEvent()
|
|
if UnitCastingInfo('player') or UnitChannelInfo('player') or UnitExists('target') or UnitExists('focus')
|
|
or UnitAffectingCombat('player') or (UnitHealth('player') ~= UnitHealthMax('player')) then
|
|
self.mouseLock = true
|
|
E:UIFrameFadeIn(self, 0.2, self:GetAlpha(), 1)
|
|
AB:FadeBlings(1)
|
|
else
|
|
self.mouseLock = false
|
|
local a = 1 - AB.db.globalFadeAlpha
|
|
E:UIFrameFadeOut(self, 0.2, self:GetAlpha(), a)
|
|
AB:FadeBlings(a)
|
|
end
|
|
end
|
|
|
|
function AB:IconIntroTracker_Toggle()
|
|
local IconIntroTracker = _G.IconIntroTracker
|
|
if AB.db.addNewSpells then
|
|
IconIntroTracker:RegisterEvent('SPELL_PUSHED_TO_ACTIONBAR')
|
|
UnregisterStateDriver(IconIntroTracker, 'visibility')
|
|
else
|
|
IconIntroTracker:UnregisterAllEvents()
|
|
RegisterStateDriver(IconIntroTracker, 'visibility', 'hide')
|
|
end
|
|
end
|
|
|
|
-- these calls are tainted when accessed by ValidateActionBarTransition
|
|
local noops = { 'ClearAllPoints', 'SetPoint', 'SetScale', 'SetShown' }
|
|
function AB:SetNoopsi(frame)
|
|
for _, func in pairs(noops) do
|
|
if frame[func] ~= E.noop then
|
|
frame[func] = E.noop
|
|
end
|
|
end
|
|
end
|
|
|
|
local SpellBookTooltip = CreateFrame('GameTooltip', 'ElvUISpellBookTooltip', E.UIParent, 'GameTooltipTemplate, BackdropTemplate')
|
|
function AB:SpellBookTooltipOnUpdate(elapsed)
|
|
self.elapsed = (self.elapsed or 0) + elapsed
|
|
if self.elapsed < TOOLTIP_UPDATE_TIME then return end
|
|
self.elapsed = 0
|
|
|
|
local owner = self:GetOwner()
|
|
if owner then AB.SpellButtonOnEnter(owner) end
|
|
end
|
|
|
|
function AB:SpellButtonOnEnter(_, tt)
|
|
-- copied from SpellBookFrame to remove:
|
|
--- ActionBarController_UpdateAll, PetActionHighlightMarks, and BarHighlightMarks
|
|
|
|
-- TT:MODIFIER_STATE_CHANGED uses this function to safely update the spellbook tooltip when the actionbar module is disabled
|
|
if not tt then tt = SpellBookTooltip end
|
|
|
|
if tt:IsForbidden() then return end
|
|
tt:SetOwner(self, 'ANCHOR_RIGHT')
|
|
|
|
local slot = _G.SpellBook_GetSpellBookSlot(self)
|
|
local needsUpdate = tt:SetSpellBookItem(slot, _G.SpellBookFrame.bookType)
|
|
|
|
ClearOnBarHighlightMarks()
|
|
ClearPetActionHighlightMarks()
|
|
|
|
local slotType, actionID = GetSpellBookItemInfo(slot, _G.SpellBookFrame.bookType)
|
|
if slotType == 'SPELL' then
|
|
UpdateOnBarHighlightMarksBySpell(actionID)
|
|
elseif slotType == 'FLYOUT' then
|
|
UpdateOnBarHighlightMarksByFlyout(actionID)
|
|
elseif slotType == 'PETACTION' then
|
|
UpdateOnBarHighlightMarksByPetAction(actionID)
|
|
UpdatePetActionHighlightMarks(actionID)
|
|
end
|
|
|
|
local highlight = self.SpellHighlightTexture
|
|
if highlight and highlight:IsShown() then
|
|
local color = _G.LIGHTBLUE_FONT_COLOR
|
|
tt:AddLine(_G.SPELLBOOK_SPELL_NOT_ON_ACTION_BAR, color.r, color.g, color.b)
|
|
end
|
|
|
|
if tt == SpellBookTooltip then
|
|
tt:SetScript('OnUpdate', (needsUpdate and AB.SpellBookTooltipOnUpdate) or nil)
|
|
end
|
|
|
|
tt:Show()
|
|
end
|
|
|
|
function AB:UpdateSpellBookTooltip(event)
|
|
-- only need to check the shown state when its not called from TT:MODIFIER_STATE_CHANGED which already checks the shown state
|
|
local button = (not event or SpellBookTooltip:IsShown()) and SpellBookTooltip:GetOwner()
|
|
if button then AB.SpellButtonOnEnter(button) end
|
|
end
|
|
|
|
function AB:SpellButtonOnLeave()
|
|
ClearOnBarHighlightMarks()
|
|
ClearPetActionHighlightMarks()
|
|
|
|
SpellBookTooltip:Hide()
|
|
SpellBookTooltip:SetScript('OnUpdate', nil)
|
|
end
|
|
|
|
function AB:ButtonEventsRegisterFrame(added)
|
|
local frames = _G.ActionBarButtonEventsFrame.frames
|
|
for index = #frames, 1, -1 do
|
|
local frame = frames[index]
|
|
local wasAdded = frame == added
|
|
if not added or wasAdded then
|
|
if not strmatch(frame:GetName(), 'ExtraActionButton%d') then
|
|
_G.ActionBarButtonEventsFrame.frames[index] = nil
|
|
end
|
|
|
|
if wasAdded then
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function AB:DisableBlizzard()
|
|
-- dont blindly add to this table, the first 5 get their events registered
|
|
for i, name in ipairs({'OverrideActionBar', 'StanceBarFrame', 'PossessBarFrame', 'PetActionBarFrame', 'MultiCastActionBarFrame', 'MainMenuBar', 'MicroButtonAndBagsBar', 'MultiBarBottomLeft', 'MultiBarBottomRight', 'MultiBarLeft', 'MultiBarRight'}) do
|
|
_G.UIPARENT_MANAGED_FRAME_POSITIONS[name] = nil
|
|
|
|
local frame = _G[name]
|
|
if i < 6 then frame:UnregisterAllEvents() end
|
|
frame:SetParent(hiddenParent)
|
|
AB:SetNoopsi(frame)
|
|
end
|
|
|
|
-- let spell book buttons work without tainting by replacing this function
|
|
for i = 1, SPELLS_PER_PAGE do
|
|
local button = _G['SpellButton'..i]
|
|
button:SetScript('OnEnter', AB.SpellButtonOnEnter)
|
|
button:SetScript('OnLeave', AB.SpellButtonOnLeave)
|
|
end
|
|
|
|
-- MainMenuBar:ClearAllPoints taint during combat
|
|
_G.MainMenuBar.SetPositionForStatusBars = E.noop
|
|
|
|
-- Spellbook open in combat taint, only happens sometimes
|
|
_G.MultiActionBar_HideAllGrids = E.noop
|
|
_G.MultiActionBar_ShowAllGrids = E.noop
|
|
|
|
-- shut down some events for things we dont use
|
|
AB:SetNoopsi(_G.MainMenuBarArtFrame)
|
|
AB:SetNoopsi(_G.MainMenuBarArtFrameBackground)
|
|
_G.MainMenuBarArtFrame:UnregisterAllEvents()
|
|
_G.StatusTrackingBarManager:UnregisterAllEvents()
|
|
_G.ActionBarButtonEventsFrame:UnregisterAllEvents()
|
|
_G.ActionBarButtonEventsFrame:RegisterEvent('ACTIONBAR_SLOT_CHANGED') -- these are needed to let the ExtraActionButton show
|
|
_G.ActionBarButtonEventsFrame:RegisterEvent('ACTIONBAR_UPDATE_COOLDOWN') -- needed for ExtraActionBar cooldown
|
|
_G.ActionBarActionEventsFrame:UnregisterAllEvents()
|
|
_G.ActionBarController:UnregisterAllEvents()
|
|
_G.ActionBarController:RegisterEvent('UPDATE_EXTRA_ACTIONBAR') -- this is needed to let the ExtraActionBar show
|
|
|
|
-- lets only keep ExtraActionButtons in here
|
|
hooksecurefunc(_G.ActionBarButtonEventsFrame, 'RegisterFrame', AB.ButtonEventsRegisterFrame)
|
|
AB.ButtonEventsRegisterFrame()
|
|
|
|
-- this would taint along with the same path as the SetNoopers: ValidateActionBarTransition
|
|
_G.VerticalMultiBarsContainer:Size(10, 10) -- dummy values so GetTop etc doesnt fail without replacing
|
|
AB:SetNoopsi(_G.VerticalMultiBarsContainer)
|
|
|
|
-- hide some interface options we dont use
|
|
_G.InterfaceOptionsActionBarsPanelStackRightBars:SetScale(0.5)
|
|
_G.InterfaceOptionsActionBarsPanelStackRightBars:SetAlpha(0)
|
|
_G.InterfaceOptionsActionBarsPanelStackRightBarsText:Hide() -- hides the !
|
|
_G.InterfaceOptionsActionBarsPanelRightTwoText:SetTextColor(1,1,1) -- no yellow
|
|
_G.InterfaceOptionsActionBarsPanelRightTwoText.SetTextColor = E.noop -- i said no yellow
|
|
_G.InterfaceOptionsActionBarsPanelAlwaysShowActionBars:SetScale(0.0001)
|
|
_G.InterfaceOptionsActionBarsPanelAlwaysShowActionBars:SetAlpha(0)
|
|
_G.InterfaceOptionsActionBarsPanelPickupActionKeyDropDownButton:SetScale(0.0001)
|
|
_G.InterfaceOptionsActionBarsPanelPickupActionKeyDropDownButton:SetAlpha(0)
|
|
_G.InterfaceOptionsActionBarsPanelPickupActionKeyDropDown:SetScale(0.0001)
|
|
_G.InterfaceOptionsActionBarsPanelPickupActionKeyDropDown:SetAlpha(0)
|
|
_G.InterfaceOptionsActionBarsPanelLockActionBars:SetScale(0.0001)
|
|
_G.InterfaceOptionsActionBarsPanelLockActionBars:SetAlpha(0)
|
|
|
|
AB:IconIntroTracker_Toggle() --Enable/disable functionality to automatically put spells on the actionbar.
|
|
AB:SecureHook('BlizzardOptionsPanel_OnEvent')
|
|
|
|
if _G.PlayerTalentFrame then
|
|
_G.PlayerTalentFrame:UnregisterEvent('ACTIVE_TALENT_GROUP_CHANGED')
|
|
else
|
|
hooksecurefunc('TalentFrame_LoadUI', function()
|
|
_G.PlayerTalentFrame:UnregisterEvent('ACTIVE_TALENT_GROUP_CHANGED')
|
|
end)
|
|
end
|
|
end
|
|
|
|
function AB:ToggleCountDownNumbers(bar, button, cd)
|
|
if cd then -- ref: E:CreateCooldownTimer
|
|
local b = cd.GetParent and cd:GetParent()
|
|
if cd.timer and (b and b.config) then
|
|
-- update the new cooldown timer button config with the new setting
|
|
b.config.disableCountDownNumbers = not not E:ToggleBlizzardCooldownText(cd, cd.timer, true)
|
|
end
|
|
elseif button then -- ref: AB:UpdateButtonConfig
|
|
if button.cooldown and button.cooldown.timer and (bar and bar.buttonConfig) then
|
|
-- button.config will get updated from `button:UpdateConfig` in `AB:UpdateButtonConfig`
|
|
bar.buttonConfig.disableCountDownNumbers = not not E:ToggleBlizzardCooldownText(button.cooldown, button.cooldown.timer, true)
|
|
end
|
|
elseif bar then -- ref: E:UpdateCooldownOverride
|
|
if bar.buttons then
|
|
for _, btn in ipairs(bar.buttons) do
|
|
if btn and btn.config and (btn.cooldown and btn.cooldown.timer) then
|
|
-- update the buttons config
|
|
btn.config.disableCountDownNumbers = not not E:ToggleBlizzardCooldownText(btn.cooldown, btn.cooldown.timer, true)
|
|
end
|
|
end
|
|
if bar.buttonConfig then
|
|
-- we can actually clear this variable because it wont get used when this code runs
|
|
bar.buttonConfig.disableCountDownNumbers = nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function AB:UpdateButtonConfig(bar, buttonName)
|
|
if InCombatLockdown() then
|
|
AB.NeedsUpdateButtonSettings = true
|
|
AB:RegisterEvent('PLAYER_REGEN_ENABLED')
|
|
return
|
|
end
|
|
|
|
if not bar.buttonConfig then bar.buttonConfig = { hideElements = {}, colors = {} } end
|
|
bar.buttonConfig.hideElements.macro = not AB.db.macrotext
|
|
bar.buttonConfig.hideElements.hotkey = not AB.db.hotkeytext
|
|
bar.buttonConfig.showGrid = AB.db['bar'..bar.id].showGrid
|
|
bar.buttonConfig.clickOnDown = AB.db.keyDown
|
|
bar.buttonConfig.outOfRangeColoring = (AB.db.useRangeColorText and 'hotkey') or 'button'
|
|
bar.buttonConfig.colors.range = E:SetColorTable(bar.buttonConfig.colors.range, AB.db.noRangeColor)
|
|
bar.buttonConfig.colors.mana = E:SetColorTable(bar.buttonConfig.colors.mana, AB.db.noPowerColor)
|
|
bar.buttonConfig.colors.usable = E:SetColorTable(bar.buttonConfig.colors.usable, AB.db.usableColor)
|
|
bar.buttonConfig.colors.notUsable = E:SetColorTable(bar.buttonConfig.colors.notUsable, AB.db.notUsableColor)
|
|
bar.buttonConfig.useDrawBling = not AB.db.hideCooldownBling
|
|
bar.buttonConfig.useDrawSwipeOnCharges = AB.db.useDrawSwipeOnCharges
|
|
bar.buttonConfig.handleOverlay = AB.db.handleOverlay
|
|
SetModifiedClick('PICKUPACTION', AB.db.movementModifier)
|
|
|
|
for i, button in ipairs(bar.buttons) do
|
|
AB:ToggleCountDownNumbers(bar, button)
|
|
|
|
bar.buttonConfig.keyBoundTarget = format(buttonName..'%d', i)
|
|
button.keyBoundTarget = bar.buttonConfig.keyBoundTarget
|
|
button.postKeybind = AB.FixKeybindText
|
|
button:SetAttribute('buttonlock', AB.db.lockActionBars)
|
|
button:SetAttribute('checkselfcast', true)
|
|
button:SetAttribute('checkfocuscast', true)
|
|
if AB.db.rightClickSelfCast then
|
|
button:SetAttribute('unit2', 'player')
|
|
end
|
|
|
|
button:UpdateConfig(bar.buttonConfig)
|
|
end
|
|
end
|
|
|
|
function AB:FixKeybindText(button)
|
|
local hotkey = _G[button:GetName()..'HotKey']
|
|
local text = hotkey:GetText()
|
|
|
|
local db = button:GetParent().db
|
|
local hotkeyPosition = db and db.customHotkeyFont and db.hotkeyTextPosition or E.db.actionbar.hotkeyTextPosition or 'TOPRIGHT'
|
|
local hotkeyXOffset = db and db.customHotkeyFont and db.hotkeyTextXOffset or E.db.actionbar.hotkeyTextXOffset or 0
|
|
local hotkeyYOffset = db and db.customHotkeyFont and db.hotkeyTextYOffset or E.db.actionbar.hotkeyTextYOffset or -3
|
|
|
|
local justify = 'RIGHT'
|
|
if hotkeyPosition == 'TOPLEFT' or hotkeyPosition == 'BOTTOMLEFT' then
|
|
justify = 'LEFT'
|
|
elseif hotkeyPosition == 'TOP' or hotkeyPosition == 'BOTTOM' then
|
|
justify = 'CENTER'
|
|
end
|
|
|
|
if text then
|
|
text = gsub(text, 'SHIFT%-', L["KEY_SHIFT"])
|
|
text = gsub(text, 'ALT%-', L["KEY_ALT"])
|
|
text = gsub(text, 'CTRL%-', L["KEY_CTRL"])
|
|
text = gsub(text, 'BUTTON', L["KEY_MOUSEBUTTON"])
|
|
text = gsub(text, 'MOUSEWHEELUP', L["KEY_MOUSEWHEELUP"])
|
|
text = gsub(text, 'MOUSEWHEELDOWN', L["KEY_MOUSEWHEELDOWN"])
|
|
text = gsub(text, 'NUMPAD', L["KEY_NUMPAD"])
|
|
text = gsub(text, 'PAGEUP', L["KEY_PAGEUP"])
|
|
text = gsub(text, 'PAGEDOWN', L["KEY_PAGEDOWN"])
|
|
text = gsub(text, 'SPACE', L["KEY_SPACE"])
|
|
text = gsub(text, 'INSERT', L["KEY_INSERT"])
|
|
text = gsub(text, 'HOME', L["KEY_HOME"])
|
|
text = gsub(text, 'DELETE', L["KEY_DELETE"])
|
|
text = gsub(text, 'NMULTIPLY', '*')
|
|
text = gsub(text, 'NMINUS', 'N-')
|
|
text = gsub(text, 'NPLUS', 'N+')
|
|
text = gsub(text, 'NEQUALS', 'N=')
|
|
|
|
hotkey:SetText(text)
|
|
hotkey:SetJustifyH(justify)
|
|
end
|
|
|
|
if not button.useMasque then
|
|
hotkey:ClearAllPoints()
|
|
hotkey:Point(hotkeyPosition, hotkeyXOffset, hotkeyYOffset)
|
|
end
|
|
end
|
|
|
|
local function flyoutButtonAnchor(frame)
|
|
local parent = frame:GetParent()
|
|
local _, parentAnchorButton = parent:GetPoint()
|
|
if not AB.handledbuttons[parentAnchorButton] then return end
|
|
|
|
return parentAnchorButton:GetParent()
|
|
end
|
|
|
|
function AB:FlyoutButton_OnEnter()
|
|
local anchor = flyoutButtonAnchor(self)
|
|
if anchor then AB:Bar_OnEnter(anchor) end
|
|
|
|
AB:BindUpdate(self, 'FLYOUT')
|
|
end
|
|
|
|
function AB:FlyoutButton_OnLeave()
|
|
local anchor = flyoutButtonAnchor(self)
|
|
if anchor then AB:Bar_OnLeave(anchor) end
|
|
end
|
|
|
|
local function spellFlyoutAnchor(frame)
|
|
local _, anchorButton = frame:GetPoint()
|
|
if not AB.handledbuttons[anchorButton] then return end
|
|
|
|
return anchorButton:GetParent()
|
|
end
|
|
|
|
function AB:SpellFlyout_OnEnter()
|
|
local anchor = spellFlyoutAnchor(self)
|
|
if anchor then AB:Bar_OnEnter(anchor) end
|
|
end
|
|
|
|
function AB:SpellFlyout_OnLeave()
|
|
local anchor = spellFlyoutAnchor(self)
|
|
if anchor then AB:Bar_OnLeave(anchor) end
|
|
end
|
|
|
|
function AB:UpdateFlyoutButtons()
|
|
local btn, i = _G['SpellFlyoutButton1'], 1
|
|
while btn do
|
|
AB:SetupFlyoutButton(btn)
|
|
btn.isFlyout = true
|
|
|
|
i = i + 1
|
|
btn = _G['SpellFlyoutButton'..i]
|
|
end
|
|
end
|
|
|
|
function AB:SetupFlyoutButton(button)
|
|
if not AB.handledbuttons[button] then
|
|
AB:StyleButton(button, nil, (MasqueGroup and E.private.actionbar.masque.actionbars) or nil)
|
|
button:HookScript('OnEnter', AB.FlyoutButton_OnEnter)
|
|
button:HookScript('OnLeave', AB.FlyoutButton_OnLeave)
|
|
end
|
|
|
|
if not InCombatLockdown() then
|
|
button:Size(AB.db.flyoutSize)
|
|
end
|
|
|
|
if MasqueGroup and E.private.actionbar.masque.actionbars then
|
|
MasqueGroup:RemoveButton(button) --Remove first to fix issue with backdrops appearing at the wrong flyout menu
|
|
MasqueGroup:AddButton(button)
|
|
end
|
|
end
|
|
|
|
function AB:StyleFlyout(button)
|
|
if not (button.FlyoutBorder and button.FlyoutArrow and button.FlyoutArrow:IsShown() and LAB.buttonRegistry[button]) then return end
|
|
|
|
button.FlyoutBorder:SetAlpha(0)
|
|
button.FlyoutBorderShadow:SetAlpha(0)
|
|
|
|
_G.SpellFlyoutHorizontalBackground:SetAlpha(0)
|
|
_G.SpellFlyoutVerticalBackground:SetAlpha(0)
|
|
_G.SpellFlyoutBackgroundEnd:SetAlpha(0)
|
|
|
|
local actionbar = button:GetParent()
|
|
local parent = actionbar and actionbar:GetParent()
|
|
local parentName = parent and parent:GetName()
|
|
if parentName == 'SpellBookSpellIconsFrame' then
|
|
return
|
|
elseif actionbar then
|
|
-- Change arrow direction depending on what bar the button is on
|
|
|
|
local arrowDistance = 2
|
|
if _G.SpellFlyout:IsShown() and _G.SpellFlyout:GetParent() == button then
|
|
arrowDistance = 5
|
|
end
|
|
|
|
local direction = (actionbar.db and actionbar.db.flyoutDirection) or 'AUTOMATIC'
|
|
local point = direction == 'AUTOMATIC' and E:GetScreenQuadrant(actionbar)
|
|
if point == 'UNKNOWN' then return end
|
|
|
|
local noCombat = not InCombatLockdown()
|
|
if direction == 'DOWN' or (point and strfind(point, 'TOP')) then
|
|
button.FlyoutArrow:ClearAllPoints()
|
|
button.FlyoutArrow:Point('BOTTOM', button, 'BOTTOM', 0, -arrowDistance)
|
|
SetClampedTextureRotation(button.FlyoutArrow, 180)
|
|
if noCombat then button:SetAttribute('flyoutDirection', 'DOWN') end
|
|
elseif direction == 'LEFT' or point == 'RIGHT' then
|
|
button.FlyoutArrow:ClearAllPoints()
|
|
button.FlyoutArrow:Point('LEFT', button, 'LEFT', -arrowDistance, 0)
|
|
SetClampedTextureRotation(button.FlyoutArrow, 270)
|
|
if noCombat then button:SetAttribute('flyoutDirection', 'LEFT') end
|
|
elseif direction == 'RIGHT' or point == 'LEFT' then
|
|
button.FlyoutArrow:ClearAllPoints()
|
|
button.FlyoutArrow:Point('RIGHT', button, 'RIGHT', arrowDistance, 0)
|
|
SetClampedTextureRotation(button.FlyoutArrow, 90)
|
|
if noCombat then button:SetAttribute('flyoutDirection', 'RIGHT') end
|
|
elseif direction == 'UP' or point == 'CENTER' or (point and strfind(point, 'BOTTOM')) then
|
|
button.FlyoutArrow:ClearAllPoints()
|
|
button.FlyoutArrow:Point('TOP', button, 'TOP', 0, arrowDistance)
|
|
SetClampedTextureRotation(button.FlyoutArrow, 0)
|
|
if noCombat then button:SetAttribute('flyoutDirection', 'UP') end
|
|
end
|
|
end
|
|
end
|
|
|
|
function AB:UpdateChargeCooldown(button, duration)
|
|
local cd = button and button.chargeCooldown
|
|
if not cd then return end
|
|
|
|
local oldstate = cd.hideText
|
|
cd.hideText = (duration and duration > 1.5) or (AB.db.chargeCooldown == false) or nil
|
|
if cd.timer and (oldstate ~= cd.hideText) then
|
|
E:ToggleBlizzardCooldownText(cd, cd.timer)
|
|
E:Cooldown_ForceUpdate(cd.timer)
|
|
end
|
|
end
|
|
|
|
function AB:ToggleCooldownOptions()
|
|
for button in pairs(LAB.actionButtons) do
|
|
if button._state_type == 'action' then
|
|
local _, duration = button:GetCooldown()
|
|
AB:UpdateChargeCooldown(button, duration)
|
|
AB:SetButtonDesaturation(button, duration)
|
|
end
|
|
end
|
|
end
|
|
|
|
function AB:SetButtonDesaturation(button, duration)
|
|
if button.LevelLinkLockIcon:IsShown() then
|
|
button.saturationLocked = nil
|
|
return
|
|
end
|
|
|
|
if AB.db.desaturateOnCooldown and (duration and duration > 1.5) then
|
|
button.icon:SetDesaturated(true)
|
|
button.saturationLocked = true
|
|
else
|
|
button.icon:SetDesaturated(false)
|
|
button.saturationLocked = nil
|
|
end
|
|
end
|
|
|
|
function AB:LAB_ChargeCreated(_, cd)
|
|
cd.CooldownOverride = 'actionbar'
|
|
E:RegisterCooldown(cd)
|
|
end
|
|
|
|
function AB:LAB_MouseUp()
|
|
if self.config.clickOnDown then
|
|
self:GetPushedTexture():SetAlpha(0)
|
|
end
|
|
end
|
|
|
|
function AB:LAB_MouseDown()
|
|
if self.config.clickOnDown then
|
|
self:GetPushedTexture():SetAlpha(1)
|
|
end
|
|
end
|
|
|
|
function AB:LAB_ButtonCreated(button)
|
|
-- this fixes Key Down getting the pushed texture stuck
|
|
button:HookScript('OnMouseUp', AB.LAB_MouseUp)
|
|
button:HookScript('OnMouseDown', AB.LAB_MouseDown)
|
|
end
|
|
|
|
function AB:LAB_ButtonUpdate(button)
|
|
local color = AB.db.fontColor
|
|
button.Count:SetTextColor(color.r, color.g, color.b)
|
|
if button.config and (button.config.outOfRangeColoring ~= 'hotkey') then
|
|
button.HotKey:SetTextColor(color.r, color.g, color.b)
|
|
end
|
|
|
|
if button.backdrop then
|
|
color = (AB.db.equippedItem and button:IsEquipped() and AB.db.equippedItemColor) or E.db.general.bordercolor
|
|
button.backdrop:SetBackdropBorderColor(color.r, color.g, color.b)
|
|
end
|
|
end
|
|
|
|
function AB:LAB_CooldownDone(button)
|
|
AB:SetButtonDesaturation(button, 0)
|
|
end
|
|
|
|
function AB:LAB_CooldownUpdate(button, _, duration)
|
|
if button._state_type == 'action' then
|
|
AB:UpdateChargeCooldown(button, duration)
|
|
AB:SetButtonDesaturation(button, duration)
|
|
end
|
|
|
|
if button.cooldown then
|
|
AB:ColorSwipeTexture(button.cooldown)
|
|
end
|
|
end
|
|
|
|
function AB:PLAYER_ENTERING_WORLD()
|
|
AB:AdjustMaxStanceButtons('PLAYER_ENTERING_WORLD')
|
|
end
|
|
|
|
function AB:Initialize()
|
|
AB.db = E.db.actionbar
|
|
|
|
if not E.private.actionbar.enable then return end
|
|
AB.Initialized = true
|
|
|
|
LAB.RegisterCallback(AB, 'OnButtonUpdate', AB.LAB_ButtonUpdate)
|
|
LAB.RegisterCallback(AB, 'OnButtonCreated', AB.LAB_ButtonCreated)
|
|
LAB.RegisterCallback(AB, 'OnChargeCreated', AB.LAB_ChargeCreated)
|
|
LAB.RegisterCallback(AB, 'OnCooldownUpdate', AB.LAB_CooldownUpdate)
|
|
LAB.RegisterCallback(AB, 'OnCooldownDone', AB.LAB_CooldownDone)
|
|
|
|
AB.fadeParent = CreateFrame('Frame', 'Elv_ABFade', _G.UIParent)
|
|
AB.fadeParent:SetAlpha(1 - AB.db.globalFadeAlpha)
|
|
AB.fadeParent:RegisterEvent('PLAYER_REGEN_DISABLED')
|
|
AB.fadeParent:RegisterEvent('PLAYER_REGEN_ENABLED')
|
|
AB.fadeParent:RegisterEvent('PLAYER_TARGET_CHANGED')
|
|
AB.fadeParent:RegisterUnitEvent('UNIT_SPELLCAST_START', 'player')
|
|
AB.fadeParent:RegisterUnitEvent('UNIT_SPELLCAST_STOP', 'player')
|
|
AB.fadeParent:RegisterUnitEvent('UNIT_SPELLCAST_CHANNEL_START', 'player')
|
|
AB.fadeParent:RegisterUnitEvent('UNIT_SPELLCAST_CHANNEL_STOP', 'player')
|
|
AB.fadeParent:RegisterUnitEvent('UNIT_HEALTH', 'player')
|
|
AB.fadeParent:RegisterEvent('PLAYER_FOCUS_CHANGED')
|
|
AB.fadeParent:SetScript('OnEvent', AB.FadeParent_OnEvent)
|
|
|
|
AB:DisableBlizzard()
|
|
AB:SetupExtraButton()
|
|
AB:SetupMicroBar()
|
|
AB:UpdateBar1Paging()
|
|
|
|
for i = 1, 10 do
|
|
AB:CreateBar(i)
|
|
end
|
|
|
|
AB:CreateBarPet()
|
|
AB:CreateBarShapeShift()
|
|
AB:CreateVehicleLeave()
|
|
AB:UpdateButtonSettings()
|
|
AB:UpdatePetCooldownSettings()
|
|
AB:ToggleCooldownOptions()
|
|
AB:LoadKeyBinder()
|
|
|
|
AB:RegisterEvent('PLAYER_ENTERING_WORLD')
|
|
AB:RegisterEvent('UPDATE_BINDINGS', 'ReassignBindings')
|
|
AB:RegisterEvent('PET_BATTLE_CLOSE', 'ReassignBindings')
|
|
AB:RegisterEvent('PET_BATTLE_OPENING_DONE', 'RemoveBindings')
|
|
AB:RegisterEvent('SPELL_UPDATE_COOLDOWN', 'UpdateSpellBookTooltip')
|
|
|
|
if _G.KeyBindingFrame then
|
|
AB:SwapKeybindButton()
|
|
else
|
|
AB:RegisterEvent('ADDON_LOADED', 'SwapKeybindButton')
|
|
end
|
|
|
|
if C_PetBattles_IsInBattle() then
|
|
AB:RemoveBindings()
|
|
else
|
|
AB:ReassignBindings()
|
|
end
|
|
|
|
-- We handle actionbar lock for regular bars, but the lock on PetBar needs to be handled by WoW so make some necessary updates
|
|
SetCVar('lockActionBars', (AB.db.lockActionBars == true and 1 or 0))
|
|
_G.LOCK_ACTIONBAR = (AB.db.lockActionBars == true and '1' or '0') -- Keep an eye on this, in case it taints
|
|
|
|
hooksecurefunc(_G.SpellFlyout, 'Show', AB.UpdateFlyoutButtons)
|
|
_G.SpellFlyout:HookScript('OnEnter', AB.SpellFlyout_OnEnter)
|
|
_G.SpellFlyout:HookScript('OnLeave', AB.SpellFlyout_OnLeave)
|
|
end
|
|
|
|
E:RegisterModule(AB:GetName())
|