local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB local UF = E:GetModule("UnitFrames") --Lua functions local random = random --WoW API / Variables local CreateFrame = CreateFrame local _, ns = ... local ElvUF = ns.oUF assert(ElvUF, "ElvUI was unable to locate oUF.") function UF:Construct_PowerBar(frame, bg, text, textPos) local power = CreateFrame("StatusBar", nil, frame) UF.statusbars[power] = true power.RaisedElementParent = CreateFrame("Frame", nil, power) power.RaisedElementParent:SetFrameLevel(power:GetFrameLevel() + 100) power.RaisedElementParent:SetAllPoints() power.PostUpdate = self.PostUpdatePower power.PostUpdateColor = self.PostUpdatePowerColor if bg then power.BG = power:CreateTexture(nil, "BORDER") power.BG:SetAllPoints() power.BG:SetTexture(E.media.blankTex) end if text then power.value = frame.RaisedElementParent:CreateFontString(nil, "OVERLAY") UF:Configure_FontString(power.value) local x = -2 if textPos == "LEFT" then x = 2 end power.value:Point(textPos, frame.Health, textPos, x, 0) power.value.frequentUpdates = true end power.colorDisconnected = false power.colorTapping = false power:CreateBackdrop("Default", nil, nil, self.thinBorders, true) local clipFrame = CreateFrame('Frame', nil, power) clipFrame:SetAllPoints() clipFrame:EnableMouse(false) clipFrame.__frame = frame power.ClipFrame = clipFrame return power end function UF:Configure_Power(frame) if not frame.VARIABLES_SET then return end local db = frame.db local power = frame.Power power.origParent = frame if frame.USE_POWERBAR then if not frame:IsElementEnabled("Power") then frame:EnableElement("Power") power:Show() end E:SetSmoothing(power, self.db.smoothbars) --Text local attachPoint = self:GetObjectAnchorPoint(frame, db.power.attachTextTo) power.value:ClearAllPoints() power.value:Point(db.power.position, attachPoint, db.power.position, db.power.xOffset, db.power.yOffset) frame:Tag(power.value, db.power.text_format) if db.power.attachTextTo == "Power" then power.value:SetParent(power.RaisedElementParent) else power.value:SetParent(frame.RaisedElementParent) end --Colors power.colorClass = nil power.colorReaction = nil power.colorPower = nil if self.db.colors.powerclass then power.colorClass = true power.colorReaction = true else power.colorPower = true end --Fix height in case it is lower than the theme allows local heightChanged = false if (not self.thinBorders and not E.PixelMode) and frame.POWERBAR_HEIGHT < 7 then --A height of 7 means 6px for borders and just 1px for the actual power statusbar frame.POWERBAR_HEIGHT = 7 if db.power then db.power.height = 7 end heightChanged = true elseif (self.thinBorders or E.PixelMode) and frame.POWERBAR_HEIGHT < 3 then --A height of 3 means 2px for borders and just 1px for the actual power statusbar frame.POWERBAR_HEIGHT = 3 if db.power then db.power.height = 3 end heightChanged = true end if heightChanged then --Update health size frame.BOTTOM_OFFSET = UF:GetHealthBottomOffset(frame) UF:Configure_HealthBar(frame) end --Position power:ClearAllPoints() if frame.POWERBAR_DETACHED then power:Width(frame.POWERBAR_WIDTH - ((frame.BORDER + frame.SPACING)*2)) power:Height(frame.POWERBAR_HEIGHT - ((frame.BORDER + frame.SPACING)*2)) if not power.Holder or (power.Holder and not power.Holder.mover) then power.Holder = CreateFrame("Frame", nil, power) power.Holder:Size(frame.POWERBAR_WIDTH, frame.POWERBAR_HEIGHT) power.Holder:Point("BOTTOM", frame, "BOTTOM", 0, -20) power:ClearAllPoints() power:Point("BOTTOMLEFT", power.Holder, "BOTTOMLEFT", frame.BORDER+frame.SPACING, frame.BORDER+frame.SPACING) --Currently only Player and Target can detach power bars, so doing it this way is okay for now if frame.unitframeType and frame.unitframeType == "player" then E:CreateMover(power.Holder, "PlayerPowerBarMover", L["Player Powerbar"], nil, nil, nil, "ALL,SOLO", nil, "unitframe,player,power") elseif frame.unitframeType and frame.unitframeType == "target" then E:CreateMover(power.Holder, "TargetPowerBarMover", L["Target Powerbar"], nil, nil, nil, "ALL,SOLO", nil, "unitframe,target,power") end else power.Holder:Size(frame.POWERBAR_WIDTH, frame.POWERBAR_HEIGHT) power:ClearAllPoints() power:Point("BOTTOMLEFT", power.Holder, "BOTTOMLEFT", frame.BORDER+frame.SPACING, frame.BORDER+frame.SPACING) power.Holder.mover:SetScale(1) power.Holder.mover:SetAlpha(1) end power:SetFrameLevel(50) --RaisedElementParent uses 100, we want lower value to allow certain icons and texts to appear above power elseif frame.USE_POWERBAR_OFFSET then if frame.ORIENTATION == "LEFT" then power:Point("TOPRIGHT", frame.Health, "TOPRIGHT", frame.POWERBAR_OFFSET + (frame.HAPPINESS_WIDTH or 0), -frame.POWERBAR_OFFSET ) power:Point("BOTTOMLEFT", frame.Health, "BOTTOMLEFT", frame.POWERBAR_OFFSET, -frame.POWERBAR_OFFSET ) elseif frame.ORIENTATION == "MIDDLE" then local totalOffset = 0 if frame.USE_ENERGYBAR and frame.USE_ENERGYBAR_OFFSET then totalOffset = totalOffset + frame.ENERGYBAR_OFFSET end if frame.USE_RAGEBAR and frame.USE_RAGEBAR_OFFSET then totalOffset = totalOffset + frame.RAGEBAR_OFFSET end power:Point("TOPLEFT", frame, "TOPLEFT", frame.BORDER + frame.SPACING + totalOffset, -(frame.POWERBAR_OFFSET + frame.CLASSBAR_YOFFSET) --+ frame.BORDER - frame.SPACING) ) power:Point("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -(frame.BORDER + frame.SPACING + totalOffset), frame.BORDER + frame.SPACING + totalOffset ) --power.WIDTH = power.WIDTH - (frame.BORDER + frame.SPACING + totalOffset) - (frame.BORDER + frame.SPACING + totalOffset) --power.HEIGHT = power.HEIGHT - (frame.BORDER + frame.SPACING + frame.CLASSBAR_YOFFSET) - (frame.BORDER + frame.SPACING + totalOffset) --[[local totalOffset = 0 if frame.USE_ENERGYBAR_OFFSET then totalOffset = totalOffset + frame.ENERGYBAR_OFFSET end if frame.USE_RAGEBAR_OFFSET then totalOffset = totalOffset + frame.RAGEBAR_OFFSET end power:Point("TOPLEFT", frame, "TOPLEFT", frame.BORDER + frame.SPACING, -frame.POWERBAR_OFFSET - frame.CLASSBAR_YOFFSET ) power:Point("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -frame.BORDER - frame.SPACING, frame.BORDER )]] else power:Point("TOPLEFT", frame.Health, "TOPLEFT", -frame.POWERBAR_OFFSET - (frame.HAPPINESS_WIDTH or 0), -frame.POWERBAR_OFFSET ) power:Point("BOTTOMRIGHT", frame.Health, "BOTTOMRIGHT", -frame.POWERBAR_OFFSET, -frame.POWERBAR_OFFSET ) end power:SetFrameLevel(frame.Health:GetFrameLevel() - 5) --Health uses 10 elseif frame.USE_INSET_POWERBAR then if frame.USE_INSET_ENERGYBAR and frame.USE_ENERGYBAR then power:Point("BOTTOMLEFT", frame.Energy, "TOPLEFT", 0, frame.BORDER * 2 ) power:Point("BOTTOMRIGHT", frame.Energy, "TOPRIGHT", 0, frame.BORDER * 2 ) else if frame.USE_INSET_RAGEBAR and frame.USE_RAGEBAR then power:Point("BOTTOMLEFT", frame.Rage, "TOPLEFT", 0, frame.BORDER * 2 ) power:Point("BOTTOMRIGHT", frame.Rage, "TOPRIGHT", 0, frame.BORDER * 2 ) else power:Point("BOTTOMLEFT", frame.Health, "BOTTOMLEFT", frame.BORDER + frame.BORDER * 2, frame.BORDER + frame.BORDER * 2 ) power:Point("BOTTOMRIGHT", frame.Health, "BOTTOMRIGHT", -(frame.BORDER + frame.BORDER * 2), frame.BORDER + frame.BORDER * 2 ) end end power:Height(frame.POWERBAR_HEIGHT - (frame.BORDER + frame.SPACING) * 2) power:SetFrameLevel(50) elseif frame.USE_MINI_POWERBAR then local totalHeight = frame.POWERBAR_HEIGHT - frame.BORDER if frame.USE_ENERGYBAR and frame.USE_MINI_ENERGYBAR then totalHeight = totalHeight + (frame.ENERGYBAR_HEIGHT - frame.BORDER) end if frame.USE_RAGEBAR and frame.USE_MINI_RAGEBAR then totalHeight = totalHeight + (frame.RAGEBAR_HEIGHT - frame.BORDER) end local yPos = totalHeight / 2 if frame.ORIENTATION == "LEFT" then power:Width(frame.POWERBAR_WIDTH - frame.BORDER * 2) power:Point("TOPRIGHT", frame.Health, "BOTTOMRIGHT", -(frame.BORDER * 2 + 4) - (frame.HAPPINESS_WIDTH or 0), yPos ) elseif frame.ORIENTATION == "RIGHT" then power:Width(frame.POWERBAR_WIDTH - frame.BORDER * 2) power:Point("TOPLEFT", frame.Health, "BOTTOMLEFT", frame.BORDER * 2 + 4 + (frame.HAPPINESS_WIDTH or 0), yPos ) else power:Point("TOPLEFT", frame.Health, "BOTTOMLEFT", frame.BORDER * 2 + 4, yPos ) power:Point("TOPRIGHT", frame.Health, "BOTTOMRIGHT", -(frame.BORDER * 2 + 4) - (frame.HAPPINESS_WIDTH or 0), yPos ) end power:Height(frame.POWERBAR_HEIGHT - (frame.BORDER + frame.SPACING) * 2) power:SetFrameLevel(50) else -- Filled power:Point("TOPRIGHT", frame.Health.backdrop, "BOTTOMRIGHT", -frame.BORDER, -frame.SPACING * 3 ) power:Point("TOPLEFT", frame.Health.backdrop, "BOTTOMLEFT", frame.BORDER, -frame.SPACING * 3 ) power:Height(frame.POWERBAR_HEIGHT - (frame.BORDER + frame.SPACING) * 2) power:SetFrameLevel(frame.Health:GetFrameLevel() - 5) end --Hide mover until we detach again if not frame.POWERBAR_DETACHED then if power.Holder and power.Holder.mover then power.Holder.mover:SetScale(0.0001) power.Holder.mover:SetAlpha(0) end end if db.power.strataAndLevel and db.power.strataAndLevel.useCustomStrata then power:SetFrameStrata(db.power.strataAndLevel.frameStrata) else power:SetFrameStrata("LOW") end if db.power.strataAndLevel and db.power.strataAndLevel.useCustomLevel then power:SetFrameLevel(db.power.strataAndLevel.frameLevel) power.backdrop:SetFrameLevel(power:GetFrameLevel() - 1) end if frame.POWERBAR_DETACHED and db.power.parent == "UIPARENT" then power:SetParent(E.UIParent) else power:SetParent(frame) end elseif frame:IsElementEnabled("Power") then frame:DisableElement("Power") power:Hide() frame:Tag(power.value, "") end power.custom_backdrop = UF.db.colors.custompowerbackdrop and UF.db.colors.power_backdrop --Transparency Settings UF:ToggleTransparentStatusBar(UF.db.colors.transparentPower, power, power.BG, nil, UF.db.colors.invertPower) end local tokens = {[0] = "MANA", "RAGE", "FOCUS", "ENERGY", "RUNIC_POWER"} function UF:PostUpdatePowerColor() local parent = self.origParent or self:GetParent() if parent.isForced then local color = ElvUF.colors.power[tokens[random(0, 4)]] self:SetValue(random(1, self.max)) if not self.colorClass then self:SetStatusBarColor(color[1], color[2], color[3]) if self.BG then UF:UpdateBackdropTextureColor(self.BG, color[1], color[2], color[3]) end end end end function UF:PostUpdatePower(unit) local parent = self.origParent or self:GetParent() if parent.isForced then self:SetValue(random(1, self.max)) end if parent.db and parent.db.power and parent.db.power.hideonnpc then UF:PostNamePosition(parent, unit) end --Force update to AdditionalPower in order to reposition text if necessary if parent:IsElementEnabled("AdditionalPower") then E:Delay(0.01, parent.AdditionalPower.ForceUpdate, parent.AdditionalPower) --Delay it slightly so Power text has a chance to clear itself first end end