local E, L, V, P, G = unpack(ElvUI); --Inport: Engine, Locales, PrivateDB, ProfileDB, GlobalDB local UF = E:GetModule("UnitFrames"); --Cache global variables --Lua functions local unpack, tonumber = unpack, tonumber local abs, min = abs, math.min --WoW API / Variables local CreateFrame = CreateFrame local UnitSpellHaste = UnitSpellHaste local UnitBuff = UnitBuff local UnitIsPlayer = UnitIsPlayer local UnitClass = UnitClass local UnitReaction = UnitReaction local UnitCanAttack = UnitCanAttack local ns = oUF local ElvUF = ns.oUF local INVERT_ANCHORPOINT = { TOPLEFT = "BOTTOMRIGHT", LEFT = "RIGHT", BOTTOMLEFT = "TOPRIGHT", RIGHT = "LEFT", TOPRIGHT = "BOTTOMLEFT", BOTTOMRIGHT = "TOPLEFT", CENTER = "CENTER", TOP = "BOTTOM", BOTTOM = "TOP", } local ticks = {} function UF:Construct_Castbar(frame, moverName) local castbar = CreateFrame("StatusBar", nil, frame) castbar:SetFrameLevel(frame.RaisedElementParent:GetFrameLevel() + 30) --Make it appear above everything else self["statusbars"][castbar] = true castbar.CustomDelayText = self.CustomCastDelayText castbar.CustomTimeText = self.CustomTimeText castbar.PostCastStart = self.PostCastStart castbar.PostChannelStart = self.PostCastStart castbar.PostCastInterruptible = self.PostCastInterruptible castbar.PostCastNotInterruptible = self.PostCastNotInterruptible castbar:SetClampedToScreen(true) E:CreateBackdrop(castbar, "Default", nil, nil, self.thinBorders, true) castbar.Time = castbar:CreateFontString(nil, "OVERLAY") self:Configure_FontString(castbar.Time) castbar.Time:SetPoint("RIGHT", castbar, "RIGHT", -4, 0) castbar.Time:SetTextColor(0.84, 0.75, 0.65) castbar.Time:SetJustifyH("RIGHT") castbar.Text = castbar:CreateFontString(nil, "OVERLAY") self:Configure_FontString(castbar.Text) castbar.Text:SetPoint("LEFT", castbar, "LEFT", 4, 0) castbar.Text:SetTextColor(0.84, 0.75, 0.65) castbar.Text:SetJustifyH("LEFT") --castbar.Text:SetWordWrap(false) castbar.Spark = castbar:CreateTexture(nil, "OVERLAY") castbar.Spark:SetBlendMode("ADD") castbar.Spark:SetVertexColor(1, 1, 1) castbar.bg = castbar:CreateTexture(nil, "BORDER") castbar.bg:Hide() local button = CreateFrame("Frame", nil, castbar) local holder = CreateFrame("Frame", nil, castbar) E:SetTemplate(button, "Default", nil, nil, self.thinBorders, true) castbar.Holder = holder --these are placeholder so the mover can be created.. it will be changed. castbar.Holder:SetPoint("TOPLEFT", frame, "BOTTOMLEFT", 0, -(frame.BORDER - frame.SPACING)) castbar:SetPoint("BOTTOMLEFT", castbar.Holder, "BOTTOMLEFT", frame.BORDER, frame.BORDER) button:SetPoint("RIGHT", castbar, "LEFT", -E.Spacing*3, 0) if moverName then E:CreateMover(castbar.Holder, frame:GetName().."CastbarMover", moverName, nil, -6, nil, "ALL,SOLO") end return castbar end function UF:Configure_Castbar(frame) if not frame.VARIABLES_SET then return end local castbar = frame.Castbar local db = frame.db castbar:SetWidth(db.castbar.width - ((frame.BORDER+frame.SPACING)*2)) castbar:SetHeight(db.castbar.height - ((frame.BORDER+frame.SPACING)*2)) castbar.Holder:SetWidth(db.castbar.width) castbar.Holder:SetHeight(db.castbar.height) if castbar.Holder:GetScript("OnSizeChanged") then castbar.Holder:GetScript("OnSizeChanged")(castbar.Holder) end if db.castbar.spark then castbar.Spark:Show() else castbar.Spark:Hide() end castbar:ClearAllPoints() if db.castbar.insideInfoPanel and frame.USE_INFO_PANEL then E:SetInside(castbar, frame.InfoPanel, 0, 0) if castbar.Holder.mover then E:DisableMover(castbar.Holder.mover:GetName()) end else local isMoved = E:HasMoverBeenMoved(frame:GetName().."CastbarMover") or not castbar.Holder.mover if not isMoved then castbar.Holder.mover:ClearAllPoints() end castbar:ClearAllPoints() if frame.ORIENTATION ~= "RIGHT" then castbar:SetPoint("BOTTOMRIGHT", castbar.Holder, "BOTTOMRIGHT", -(frame.BORDER+frame.SPACING), frame.BORDER+frame.SPACING) if not isMoved then castbar.Holder.mover:SetPoint("TOPRIGHT", frame, "BOTTOMRIGHT", 0, -(frame.BORDER - frame.SPACING)) end else castbar:SetPoint("BOTTOMLEFT", castbar.Holder, "BOTTOMLEFT", frame.BORDER+frame.SPACING, frame.BORDER+frame.SPACING) if not isMoved then castbar.Holder.mover:SetPoint("TOPLEFT", frame, "BOTTOMLEFT", 0, -(frame.BORDER - frame.SPACING)) end end if castbar.Holder.mover then E:EnableMover(castbar.Holder.mover:GetName()) end end if db.castbar.enable and not frame:IsElementEnabled("Castbar") then frame:EnableElement("Castbar") elseif not db.castbar.enable and frame:IsElementEnabled("Castbar") then frame:DisableElement("Castbar") if(castbar.Holder.mover) then E:DisableMover(castbar.Holder.mover:GetName()) end end end function UF:CustomCastDelayText(duration) local db = self:GetParent().db if not db then return end if self.channeling then if db.castbar.format == "CURRENT" then self.Time:SetText(format("%.1f |cffaf5050%.1f|r", abs(duration - self.max), self.delay)) elseif db.castbar.format == "CURRENTMAX" then self.Time:SetText(format("%.1f / %.1f |cffaf5050%.1f|r", duration, self.max, self.delay)) elseif db.castbar.format == "REMAINING" then self.Time:SetText(format("%.1f |cffaf5050%.1f|r", duration, self.delay)) end else if db.castbar.format == "CURRENT" then self.Time:SetText(format("%.1f |cffaf5050%s %.1f|r", duration, "+", self.delay)) elseif db.castbar.format == "CURRENTMAX" then self.Time:SetText(format("%.1f / %.1f |cffaf5050%s %.1f|r", duration, self.max, "+", self.delay)) elseif db.castbar.format == "REMAINING" then self.Time:SetText(format("%.1f |cffaf5050%s %.1f|r", abs(duration - self.max), "+", self.delay)) end end end function UF:CustomTimeText(duration) local db = self:GetParent().db if not db then return end if self.channeling then if db.castbar.format == "CURRENT" then self.Time:SetText(format("%.1f", abs(duration - self.max))) elseif db.castbar.format == "CURRENTMAX" then self.Time:SetText(format("%.1f / %.1f", duration, self.max)) self.Time:SetText(format("%.1f / %.1f", abs(duration - self.max), self.max)) elseif db.castbar.format == "REMAINING" then self.Time:SetText(format("%.1f", duration)) end else if db.castbar.format == "CURRENT" then self.Time:SetText(format("%.1f", duration)) elseif db.castbar.format == "CURRENTMAX" then self.Time:SetText(format("%.1f / %.1f", duration, self.max)) elseif db.castbar.format == "REMAINING" then self.Time:SetText(format("%.1f", abs(duration - self.max))) end end end function UF:PostCastStart(name) local db = self:GetParent().db if not db or not db.castbar then return; end self.Text:SetText(name) -- Get length of Time, then calculate available length for Text local timeWidth = self.Time:GetStringWidth() local textWidth = self:GetWidth() - timeWidth - 10 local textStringWidth = self.Text:GetStringWidth() if timeWidth == 0 or textStringWidth == 0 then E:Delay(0.05, function() -- Delay may need tweaking textWidth = self:GetWidth() - self.Time:GetStringWidth() - 10 textStringWidth = self.Text:GetStringWidth() if textWidth > 0 then self.Text:SetWidth(min(textWidth, textStringWidth)) end end) else self.Text:SetWidth(min(textWidth, textStringWidth)) end self.Spark:SetHeight(self:GetHeight() * 2) local colors = ElvUF.colors local r, g, b = colors.castColor[1], colors.castColor[2], colors.castColor[3] local t if UF.db.colors.castClassColor and UnitIsPlayer("player") then local _, class = UnitClass("player") t = ElvUF.colors.class[class] elseif UF.db.colors.castReactionColor and UnitReaction("player", "player") then t = ElvUF.colors.reaction[UnitReaction("player", "player")] end if t then r, g, b = t[1], t[2], t[3] end --[[ if self.notInterruptible and unit ~= "player" and UnitCanAttack("player", unit) then r, g, b = colors.castNoInterrupt[1], colors.castNoInterrupt[2], colors.castNoInterrupt[3] end ]] self:SetStatusBarColor(r, g, b) UF:ToggleTransparentStatusBar(UF.db.colors.transparentCastbar, self, self.bg, nil, true) if self.bg:IsShown() then self.bg:SetColorTexture(r * 0.25, g * 0.25, b * 0.25) local _, _, _, alpha = self.backdrop:GetBackdropColor() self.backdrop:SetBackdropColor(r * 0.58, g * 0.58, b * 0.58, alpha) end end function UF:PostCastInterruptible() local colors = ElvUF.colors local r, g, b = colors.castColor[1], colors.castColor[2], colors.castColor[3] local t if UF.db.colors.castClassColor and UnitIsPlayer("player") then local _, class = UnitClass("player") t = ElvUF.colors.class[class] elseif UF.db.colors.castReactionColor and UnitReaction("player", "player") then t = ElvUF.colors.reaction[UnitReaction("player", "player")] end if t then r, g, b = t[1], t[2], t[3] end --[[ if self.notInterruptible and UnitCanAttack("player", unit) then r, g, b = colors.castNoInterrupt[1], colors.castNoInterrupt[2], colors.castNoInterrupt[3] end ]] self:SetStatusBarColor(r, g, b) UF:ToggleTransparentStatusBar(UF.db.colors.transparentCastbar, self, self.bg, nil, true) if self.bg:IsShown() then self.bg:SetColorTexture(r * 0.25, g * 0.25, b * 0.25) local _, _, _, alpha = self.backdrop:GetBackdropColor() self.backdrop:SetBackdropColor(r * 0.58, g * 0.58, b * 0.58, alpha) end end function UF:PostCastNotInterruptible() local colors = ElvUF.colors self:SetStatusBarColor(colors.castNoInterrupt[1], colors.castNoInterrupt[2], colors.castNoInterrupt[3]) end