local E, L, V, P, G = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB local AB = E:GetModule("ActionBars"); --Cache global variables --Lua functions local _G = _G local ceil, mod = math.ceil, math.mod --WoW API / Variables local CreateFrame = CreateFrame local GetNumShapeshiftForms = GetNumShapeshiftForms local GetShapeshiftFormCooldown = GetShapeshiftFormCooldown local GetShapeshiftFormInfo = GetShapeshiftFormInfo local GetBindingKey = GetBindingKey local NUM_SHAPESHIFT_SLOTS = NUM_SHAPESHIFT_SLOTS local bar = CreateFrame("Frame", "ElvUI_StanceBar", E.UIParent) function AB:SPELL_UPDATE_COOLDOWN() local numForms = GetNumShapeshiftForms() local start, duration, enable, cooldown for i = 1, NUM_SHAPESHIFT_SLOTS do if i <= numForms then cooldown = _G["ElvUI_StanceBarButton"..i.."Cooldown"] start, duration, enable = GetShapeshiftFormCooldown(i) CooldownFrame_SetTimer(cooldown, start, duration, enable) end end self:StyleShapeShift("SPELL_UPDATE_COOLDOWN") end function AB:StyleShapeShift() local buttonName, button, icon, cooldown local texture, name, isActive, isCastable, _ local numForms = GetNumShapeshiftForms() for i = 1, NUM_SHAPESHIFT_SLOTS do buttonName = "ElvUI_StanceBarButton"..i button = _G[buttonName] icon = _G[buttonName.."Icon"] cooldown = _G[buttonName.."Cooldown"] if i <= numForms then texture, name, isActive, isCastable = GetShapeshiftFormInfo(i) if self.db.barShapeShift.style == "darkenInactive" then if name then texture = texture end end if not texture then texture = "Interface\\Icons\\Spell_Nature_WispSplode" end icon:SetTexture(texture) if texture then cooldown:SetAlpha(1) else cooldown:SetAlpha(0) end if isActive then ShapeshiftBarFrame.lastSelected = button:GetID() if numForms == 1 then button:GetCheckedTexture():SetTexture(1, 1, 1, 0.5) button:SetChecked(true) else button:GetCheckedTexture():SetTexture(1, 1, 1, 0.5) button:SetChecked(self.db.barShapeShift.style ~= "darkenInactive") end else if numForms == 1 then button:SetChecked(false) else button:SetChecked(self.db.barShapeShift.style == "darkenInactive") button:GetCheckedTexture():SetAlpha(1) if self.db.barShapeShift.style == "darkenInactive" then button:GetCheckedTexture():SetTexture(0, 0, 0, 0.5) else button:GetCheckedTexture():SetTexture(1, 1, 1, 0.5) end end end if isCastable then icon:SetVertexColor(1.0, 1.0, 1.0) else icon:SetVertexColor(0.4, 0.4, 0.4) end end end end function AB:PositionAndSizeBarShapeShift() local buttonSpacing = E:Scale(self.db["barShapeShift"].buttonspacing) local backdropSpacing = E:Scale((self.db["barShapeShift"].backdropSpacing or self.db["barShapeShift"].buttonspacing)) local buttonsPerRow = self.db["barShapeShift"].buttonsPerRow local numButtons = self.db["barShapeShift"].buttons local size = E:Scale(self.db["barShapeShift"].buttonsize) local point = self.db["barShapeShift"].point local widthMult = self.db["barShapeShift"].widthMult local heightMult = self.db["barShapeShift"].heightMult if bar.mover then bar.mover.positionOverride = point E:UpdatePositionOverride(bar:GetName()) end bar.db = self.db["barShapeShift"] bar.db.position = nil --Depreciated bar.mouseover = self.db["barShapeShift"].mouseover if bar.LastButton and numButtons > bar.LastButton then numButtons = bar.LastButton end if bar.LastButton and buttonsPerRow > bar.LastButton then buttonsPerRow = bar.LastButton end if numButtons < buttonsPerRow then buttonsPerRow = numButtons end local numColumns = ceil(numButtons / buttonsPerRow) if numColumns < 1 then numColumns = 1 end if self.db["barShapeShift"].backdrop == true then bar.backdrop:Show() else bar.backdrop:Hide() widthMult = 1 heightMult = 1 end local barWidth = (size * (buttonsPerRow * widthMult)) + ((buttonSpacing * (buttonsPerRow - 1)) * widthMult) + (buttonSpacing * (widthMult-1)) + ((self.db["barShapeShift"].backdrop == true and (E.Border + backdropSpacing) or E.Spacing)*2) local barHeight = (size * (numColumns * heightMult)) + ((buttonSpacing * (numColumns - 1)) * heightMult) + (buttonSpacing * (heightMult-1)) + ((self.db["barShapeShift"].backdrop == true and (E.Border + backdropSpacing) or E.Spacing)*2) E:Size(bar, barWidth, barHeight) if self.db["barShapeShift"].enabled then bar:SetScale(1) bar:SetAlpha(bar.db.alpha) E:EnableMover(bar.mover:GetName()) E:Point(bar, "CENTER", 0, 0) else bar:SetScale(0.0001) bar:SetAlpha(0) E:DisableMover(bar.mover:GetName()) end local horizontalGrowth, verticalGrowth if point == "TOPLEFT" or point == "TOPRIGHT" then verticalGrowth = "DOWN" else verticalGrowth = "UP" end if point == "BOTTOMLEFT" or point == "TOPLEFT" then horizontalGrowth = "RIGHT" else horizontalGrowth = "LEFT" end if self.db["barShapeShift"].inheritGlobalFade then bar:SetParent(self.fadeParent) else bar:SetParent(E.UIParent) end local button, lastButton, lastColumnButton local firstButtonSpacing = (self.db["barShapeShift"].backdrop == true and (E.Border + backdropSpacing) or E.Spacing) for i = 1, NUM_SHAPESHIFT_SLOTS do button = _G["ElvUI_StanceBarButton"..i] lastButton = _G["ElvUI_StanceBarButton"..i-1] lastColumnButton = _G["ElvUI_StanceBarButton"..i-buttonsPerRow] button:SetParent(bar) button:ClearAllPoints() E:Size(button, size) _G[button:GetName().."Cooldown"]:SetModelScale(size / 40) if self.db["barShapeShift"].mouseover == true then bar:SetAlpha(0) else bar:SetAlpha(bar.db.alpha) end if i == 1 then local x, y if point == "BOTTOMLEFT" then x, y = firstButtonSpacing, firstButtonSpacing elseif point == "TOPRIGHT" then x, y = -firstButtonSpacing, -firstButtonSpacing elseif point == "TOPLEFT" then x, y = firstButtonSpacing, -firstButtonSpacing else x, y = -firstButtonSpacing, firstButtonSpacing end E:Point(button, point, bar, point, x, y) elseif mod((i - 1), buttonsPerRow) == 0 then local x = 0 local y = -buttonSpacing local buttonPoint, anchorPoint = "TOP", "BOTTOM" if verticalGrowth == "UP" then y = buttonSpacing buttonPoint = "BOTTOM" anchorPoint = "TOP" end E:Point(button, buttonPoint, lastColumnButton, anchorPoint, x, y) else local x = buttonSpacing local y = 0 local buttonPoint, anchorPoint = "LEFT", "RIGHT" if horizontalGrowth == "LEFT" then x = -buttonSpacing buttonPoint = "RIGHT" anchorPoint = "LEFT" end E:Point(button, buttonPoint, lastButton, anchorPoint, x, y) end if i > numButtons then button:SetScale(0.0001) button:SetAlpha(0) else button:SetScale(1) button:SetAlpha(bar.db.alpha) end if not button.FlyoutUpdateFunc then self:StyleButton(button, nil, self.LBFGroup and E.private.actionbar.lbf.enable and true or nil) end end if (self.LBFGroup and E.private.actionbar.lbf.enable) then self.LBFGroup:Skin(E.private.actionbar.lbf.skin) end end function AB:AdjustMaxStanceButtons(event) for i = 1, getn(bar.buttons) do bar.buttons[i]:Hide() end local numButtons = GetNumShapeshiftForms() for i = 1, NUM_SHAPESHIFT_SLOTS do if not bar.buttons[i] then bar.buttons[i] = CreateFrame("CheckButton", format(bar:GetName().."Button%d", i), bar, "ShapeshiftButtonTemplate") bar.buttons[i]:SetID(i) if self.LBFGroup and E.private.actionbar.lbf.enable then self.LBFGroup:AddButton(bar.buttons[i]) end self:HookScript(bar.buttons[i], "OnEnter", "Button_OnEnter") self:HookScript(bar.buttons[i], "OnLeave", "Button_OnLeave") end if i <= numButtons then bar.buttons[i]:Show() bar.LastButton = i else bar.buttons[i]:Hide() end end self:PositionAndSizeBarShapeShift() if event == "UPDATE_SHAPESHIFT_FORMS" then self:StyleShapeShift() end end function AB:UpdateStanceBindings() for i = 1, NUM_SHAPESHIFT_SLOTS do if self.db.hotkeytext then _G["ElvUI_StanceBarButton"..i.."HotKey"]:Show() _G["ElvUI_StanceBarButton"..i.."HotKey"]:SetText(GetBindingKey("SHAPESHIFTBUTTON" .. i)) self:FixKeybindText(_G["ElvUI_StanceBarButton"..i]) else _G["ElvUI_StanceBarButton"..i.."HotKey"]:Hide() end end end function AB:CreateBarShapeShift() E:CreateBackdrop(bar, "Default") bar.backdrop:SetAllPoints() E:Point(bar, "TOPLEFT", E.UIParent, "TOPLEFT", 4, -4) bar.buttons = {} self:HookScript(bar, "OnEnter", "Bar_OnEnter") self:HookScript(bar, "OnLeave", "Bar_OnLeave") self:RegisterEvent("UPDATE_SHAPESHIFT_FORMS", "AdjustMaxStanceButtons") self:RegisterEvent("SPELL_UPDATE_COOLDOWN") self:RegisterEvent("SPELL_UPDATE_USABLE", "StyleShapeShift") self:RegisterEvent("PLAYER_AURAS_CHANGED", "StyleShapeShift") self:RegisterEvent("ACTIONBAR_PAGE_CHANGED", "StyleShapeShift") E:CreateMover(bar, "ShiftAB", L["Stance Bar"], nil, -3, nil, "ALL,ACTIONBARS") self:AdjustMaxStanceButtons() self:PositionAndSizeBarShapeShift() self:StyleShapeShift() self:UpdateStanceBindings() end