This commit is contained in:
Logan Payton
2018-03-03 17:48:49 -05:00
parent 7207a84dc6
commit 0969370c94
3 changed files with 652 additions and 60 deletions
+57 -59
View File
@@ -65,7 +65,7 @@ local ns = oUF
local oUF = ns.oUF local oUF = ns.oUF
local tinsert = table.insert local tinsert = table.insert
local floor = math.floor local floor, min = math.floor, math.min
local CreateFrame = CreateFrame local CreateFrame = CreateFrame
local GetTime = GetTime local GetTime = GetTime
@@ -83,7 +83,7 @@ local function UpdateTooltip(self)
end end
local function onEnter(self) local function onEnter(self)
if(not self:IsVisible()) then return end if not self:IsVisible() then return end
GameTooltip:SetOwner(self, 'ANCHOR_BOTTOMRIGHT') GameTooltip:SetOwner(self, 'ANCHOR_BOTTOMRIGHT')
self:UpdateTooltip() self:UpdateTooltip()
@@ -126,15 +126,13 @@ local function createAuraIcon(element, index)
* self - the widget holding the aura buttons * self - the widget holding the aura buttons
* button - the newly created aura button (Button) * button - the newly created aura button (Button)
--]] --]]
if(element.PostCreateIcon) then element:PostCreateIcon(button) end if element.PostCreateIcon then element:PostCreateIcon(button) end
return button return button
end end
local function customFilter(element, unit, button, name) local function customFilter(element, unit, button, name)
if(name) then if name then return true end
return true
end
end end
local function updateIcon(element, unit, index, offset, filter, isDebuff, visible) local function updateIcon(element, unit, index, offset, filter, isDebuff, visible)
@@ -185,12 +183,12 @@ local function updateIcon(element, unit, index, offset, filter, isDebuff, visibl
show = (element.CustomFilter or customFilter) (element, unit, button, name, rank, texture, count, dispelType, duration, expiration) show = (element.CustomFilter or customFilter) (element, unit, button, name, rank, texture, count, dispelType, duration, expiration)
end end
if(show) then if show then
-- We might want to consider delaying the creation of an actual cooldown -- We might want to consider delaying the creation of an actual cooldown
-- object to this point, but I think that will just make things needlessly -- object to this point, but I think that will just make things needlessly
-- complicated. -- complicated.
if(button.cd and not element.disableCooldown) then if button.cd and not element.disableCooldown then
if(duration and duration > 0) then if duration and duration > 0 then
button.cd:SetCooldown(GetTime() - (duration - expiration), duration) button.cd:SetCooldown(GetTime() - (duration - expiration), duration)
button.cd:Show() button.cd:Show()
else else
@@ -198,8 +196,8 @@ local function updateIcon(element, unit, index, offset, filter, isDebuff, visibl
end end
end end
if(button.overlay) then if button.overlay then
if((isDebuff and element.showDebuffType) or (not isDebuff and element.showBuffType) or element.showType) then if (isDebuff and element.showDebuffType) or (not isDebuff and element.showBuffType) or element.showType then
local color = DebuffTypeColor[dispelType] or DebuffTypeColor.none local color = DebuffTypeColor[dispelType] or DebuffTypeColor.none
button.overlay:SetVertexColor(color.r, color.g, color.b) button.overlay:SetVertexColor(color.r, color.g, color.b)
@@ -209,8 +207,8 @@ local function updateIcon(element, unit, index, offset, filter, isDebuff, visibl
end end
end end
if(button.icon) then button.icon:SetTexture(texture) end if button.icon then button.icon:SetTexture(texture) end
if(button.count) then button.count:SetText(count > 1 and count) end if button.count then button.count:SetText(count > 1 and count) end
local size = element.size or 16 local size = element.size or 16
button:SetSize(size, size) button:SetSize(size, size)
@@ -228,7 +226,7 @@ local function updateIcon(element, unit, index, offset, filter, isDebuff, visibl
* index - the index of the aura (number) * index - the index of the aura (number)
* position - the actual position of the aura button (number) * position - the actual position of the aura button (number)
--]] --]]
if(element.PostUpdateIcon) then if element.PostUpdateIcon then
element:PostUpdateIcon(unit, button, index, position) element:PostUpdateIcon(unit, button, index, position)
end end
@@ -261,24 +259,24 @@ local function SetPosition(element, from, to)
end end
local function filterIcons(element, unit, filter, limit, isDebuff, offset, dontHide) local function filterIcons(element, unit, filter, limit, isDebuff, offset, dontHide)
if(not offset) then offset = 0 end if not offset then offset = 0 end
local index = 1 local index = 1
local visible = 0 local visible = 0
local hidden = 0 local hidden = 0
while(visible < limit) do while visible < limit do
local result = updateIcon(element, unit, index, offset, filter, isDebuff, visible) local result = updateIcon(element, unit, index, offset, filter, isDebuff, visible)
if(not result) then if not result then
break break
elseif(result == VISIBLE) then elseif result == VISIBLE then
visible = visible + 1 visible = visible + 1
elseif(result == HIDDEN) then elseif result == HIDDEN then
hidden = hidden + 1 hidden = hidden + 1
end end
index = index + 1 index = index + 1
end end
if(not dontHide) then if not dontHide then
for i = visible + offset + 1, #element do for i = visible + offset + 1, #element do
element[i]:Hide() element[i]:Hide()
end end
@@ -288,42 +286,42 @@ local function filterIcons(element, unit, filter, limit, isDebuff, offset, dontH
end end
local function UpdateAuras(self, event, unit) local function UpdateAuras(self, event, unit)
if(self.unit ~= unit) then return end if self.unit ~= unit then return end
local auras = self.Auras local auras = self.Auras
if(auras) then if auras then
--[[ Callback: Auras:PreUpdate(unit) --[[ Callback: Auras:PreUpdate(unit)
Called before the element has been updated. Called before the element has been updated.
* self - the widget holding the aura buttons * self - the widget holding the aura buttons
* unit - the unit for which the update has been triggered (string) * unit - the unit for which the update has been triggered (string)
--]] --]]
if(auras.PreUpdate) then auras:PreUpdate(unit) end if auras.PreUpdate then auras:PreUpdate(unit) end
local numBuffs = auras.numBuffs or 32 local numBuffs = auras.numBuffs or 32
local numDebuffs = auras.numDebuffs or 40 local numDebuffs = auras.numDebuffs or 40
local max = auras.numTotal or numBuffs + numDebuffs local max = auras.numTotal or numBuffs + numDebuffs
local visibleBuffs, hiddenBuffs = filterIcons(auras, unit, auras.buffFilter or auras.filter or 'HELPFUL', math.min(numBuffs, max), nil, 0, true) local visibleBuffs, hiddenBuffs = filterIcons(auras, unit, auras.buffFilter or auras.filter or 'HELPFUL', min(numBuffs, max), nil, 0, true)
local hasGap local hasGap
if(visibleBuffs ~= 0 and auras.gap) then if visibleBuffs ~= 0 and auras.gap then
hasGap = true hasGap = true
visibleBuffs = visibleBuffs + 1 visibleBuffs = visibleBuffs + 1
local button = auras[visibleBuffs] local button = auras[visibleBuffs]
if(not button) then if not button then
button = (auras.CreateIcon or createAuraIcon) (auras, visibleBuffs) button = (auras.CreateIcon or createAuraIcon) (auras, visibleBuffs)
tinsert(auras, button) tinsert(auras, button)
auras.createdIcons = auras.createdIcons + 1 auras.createdIcons = auras.createdIcons + 1
end end
-- Prevent the button from displaying anything. -- Prevent the button from displaying anything.
if(button.cd) then button.cd:Hide() end if button.cd then button.cd:Hide() end
if(button.icon) then button.icon:SetTexture() end if button.icon then button.icon:SetTexture() end
if(button.overlay) then button.overlay:Hide() end if button.overlay then button.overlay:Hide() end
if(button.stealable) then button.stealable:Hide() end if button.stealable then button.stealable:Hide() end
if(button.count) then button.count:SetText() end if button.count then button.count:SetText() end
button:EnableMouse(false) button:EnableMouse(false)
button:Show() button:Show()
@@ -341,10 +339,10 @@ local function UpdateAuras(self, event, unit)
end end
end end
local visibleDebuffs, hiddenDebuffs = filterIcons(auras, unit, auras.debuffFilter or auras.filter or 'HARMFUL', math.min(numDebuffs, max - visibleBuffs), true, visibleBuffs) local visibleDebuffs, hiddenDebuffs = filterIcons(auras, unit, auras.debuffFilter or auras.filter or 'HARMFUL', min(numDebuffs, max - visibleBuffs), true, visibleBuffs)
auras.visibleDebuffs = visibleDebuffs auras.visibleDebuffs = visibleDebuffs
if(hasGap and visibleDebuffs == 0) then if hasGap and visibleDebuffs == 0 then
auras[visibleBuffs]:Hide() auras[visibleBuffs]:Hide()
visibleBuffs = visibleBuffs - 1 visibleBuffs = visibleBuffs - 1
end end
@@ -364,11 +362,11 @@ local function UpdateAuras(self, event, unit)
* from - the offset of the first aura button to be (re-)anchored (number) * from - the offset of the first aura button to be (re-)anchored (number)
* to - the offset of the last aura button to be (re-)anchored (number) * to - the offset of the last aura button to be (re-)anchored (number)
--]] --]]
if(auras.PreSetPosition) then if auras.PreSetPosition then
fromRange, toRange = auras:PreSetPosition(max) fromRange, toRange = auras:PreSetPosition(max)
end end
if(fromRange or auras.createdIcons > auras.anchoredIcons) then if fromRange or auras.createdIcons > auras.anchoredIcons then
--[[ Override: Auras:SetPosition(from, to) --[[ Override: Auras:SetPosition(from, to)
Used to (re-)anchor the aura buttons. Used to (re-)anchor the aura buttons.
Called when new aura buttons have been created or if :PreSetPosition is defined. Called when new aura buttons have been created or if :PreSetPosition is defined.
@@ -387,72 +385,72 @@ local function UpdateAuras(self, event, unit)
* self - the widget holding the aura buttons * self - the widget holding the aura buttons
* unit - the unit for which the update has been triggered (string) * unit - the unit for which the update has been triggered (string)
--]] --]]
if(auras.PostUpdate) then auras:PostUpdate(unit) end if auras.PostUpdate then auras:PostUpdate(unit) end
end end
local buffs = self.Buffs local buffs = self.Buffs
if(buffs) then if buffs then
if(buffs.PreUpdate) then buffs:PreUpdate(unit) end if buffs.PreUpdate then buffs:PreUpdate(unit) end
local numBuffs = buffs.num or 32 local numBuffs = buffs.num or 32
local visibleBuffs, hiddenBuffs = filterIcons(buffs, unit, buffs.filter or 'HELPFUL', numBuffs) local visibleBuffs, hiddenBuffs = filterIcons(buffs, unit, buffs.filter or 'HELPFUL', numBuffs)
buffs.visibleBuffs = visibleBuffs buffs.visibleBuffs = visibleBuffs
local fromRange, toRange local fromRange, toRange
if(buffs.PreSetPosition) then if buffs.PreSetPosition then
fromRange, toRange = buffs:PreSetPosition(numBuffs) fromRange, toRange = buffs:PreSetPosition(numBuffs)
end end
if(fromRange or buffs.createdIcons > buffs.anchoredIcons) then if fromRange or buffs.createdIcons > buffs.anchoredIcons then
(buffs.SetPosition or SetPosition) (buffs, fromRange or buffs.anchoredIcons + 1, toRange or buffs.createdIcons) (buffs.SetPosition or SetPosition) (buffs, fromRange or buffs.anchoredIcons + 1, toRange or buffs.createdIcons)
buffs.anchoredIcons = buffs.createdIcons buffs.anchoredIcons = buffs.createdIcons
end end
if(buffs.PostUpdate) then buffs:PostUpdate(unit) end if buffs.PostUpdate then buffs:PostUpdate(unit) end
end end
local debuffs = self.Debuffs local debuffs = self.Debuffs
if(debuffs) then if debuffs then
if(debuffs.PreUpdate) then debuffs:PreUpdate(unit) end if debuffs.PreUpdate then debuffs:PreUpdate(unit) end
local numDebuffs = debuffs.num or 40 local numDebuffs = debuffs.num or 40
local visibleDebuffs, hiddenDebuffs = filterIcons(debuffs, unit, debuffs.filter or 'HARMFUL', numDebuffs, true) local visibleDebuffs, hiddenDebuffs = filterIcons(debuffs, unit, debuffs.filter or 'HARMFUL', numDebuffs, true)
debuffs.visibleDebuffs = visibleDebuffs debuffs.visibleDebuffs = visibleDebuffs
local fromRange, toRange local fromRange, toRange
if(debuffs.PreSetPosition) then if debuffs.PreSetPosition then
fromRange, toRange = debuffs:PreSetPosition(numDebuffs) fromRange, toRange = debuffs:PreSetPosition(numDebuffs)
end end
if(fromRange or debuffs.createdIcons > debuffs.anchoredIcons) then if fromRange or debuffs.createdIcons > debuffs.anchoredIcons then
(debuffs.SetPosition or SetPosition) (debuffs, fromRange or debuffs.anchoredIcons + 1, toRange or debuffs.createdIcons) (debuffs.SetPosition or SetPosition) (debuffs, fromRange or debuffs.anchoredIcons + 1, toRange or debuffs.createdIcons)
debuffs.anchoredIcons = debuffs.createdIcons debuffs.anchoredIcons = debuffs.createdIcons
end end
if(debuffs.PostUpdate) then debuffs:PostUpdate(unit) end if debuffs.PostUpdate then debuffs:PostUpdate(unit) end
end end
end end
local function Update(self, event, unit) local function Update(self, event, unit)
if(self.unit ~= unit) then return end if self.unit ~= unit then return end
UpdateAuras(self, event, unit) UpdateAuras(self, event, unit)
-- Assume no event means someone wants to re-anchor things. This is usually -- Assume no event means someone wants to re-anchor things. This is usually
-- done by UpdateAllElements and :ForceUpdate. -- done by UpdateAllElements and :ForceUpdate.
if(event == 'ForceUpdate' or not event) then if event == 'ForceUpdate' or not event then
local buffs = self.Buffs local buffs = self.Buffs
if(buffs) then if buffs then
(buffs.SetPosition or SetPosition) (buffs, 1, buffs.createdIcons) (buffs.SetPosition or SetPosition) (buffs, 1, buffs.createdIcons)
end end
local debuffs = self.Debuffs local debuffs = self.Debuffs
if(debuffs) then if debuffs then
(debuffs.SetPosition or SetPosition) (debuffs, 1, debuffs.createdIcons) (debuffs.SetPosition or SetPosition) (debuffs, 1, debuffs.createdIcons)
end end
local auras = self.Auras local auras = self.Auras
if(auras) then if auras then
(auras.SetPosition or SetPosition) (auras, 1, auras.createdIcons) (auras.SetPosition or SetPosition) (auras, 1, auras.createdIcons)
end end
end end
@@ -463,11 +461,11 @@ local function ForceUpdate(element)
end end
local function Enable(self) local function Enable(self)
if(self.Buffs or self.Debuffs or self.Auras) then if self.Buffs or self.Debuffs or self.Auras then
self:RegisterEvent('UNIT_AURA', UpdateAuras) self:RegisterEvent('UNIT_AURA', UpdateAuras)
local buffs = self.Buffs local buffs = self.Buffs
if(buffs) then if buffs then
buffs.__owner = self buffs.__owner = self
buffs.ForceUpdate = ForceUpdate buffs.ForceUpdate = ForceUpdate
@@ -478,7 +476,7 @@ local function Enable(self)
end end
local debuffs = self.Debuffs local debuffs = self.Debuffs
if(debuffs) then if debuffs then
debuffs.__owner = self debuffs.__owner = self
debuffs.ForceUpdate = ForceUpdate debuffs.ForceUpdate = ForceUpdate
@@ -489,7 +487,7 @@ local function Enable(self)
end end
local auras = self.Auras local auras = self.Auras
if(auras) then if auras then
auras.__owner = self auras.__owner = self
auras.ForceUpdate = ForceUpdate auras.ForceUpdate = ForceUpdate
@@ -504,12 +502,12 @@ local function Enable(self)
end end
local function Disable(self) local function Disable(self)
if(self.Buffs or self.Debuffs or self.Auras) then if self.Buffs or self.Debuffs or self.Auras then
self:UnregisterEvent('UNIT_AURA', UpdateAuras) self:UnregisterEvent('UNIT_AURA', UpdateAuras)
if(self.Buffs) then self.Buffs:Hide() end if self.Buffs then self.Buffs:Hide() end
if(self.Debuffs) then self.Debuffs:Hide() end if self.Debuffs then self.Debuffs:Hide() end
if(self.Auras) then self.Auras:Hide() end if self.Auras then self.Auras:Hide() end
end end
end end
+593
View File
@@ -0,0 +1,593 @@
local E, L, V, P, G = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local UF = E:GetModule("UnitFrames");
local LSM = LibStub("LibSharedMedia-3.0");
--Cache global variables
--Lua functions
local unpack = unpack
local find, format = string.find, string.format
local strsplit = strsplit
local tsort, getn = table.sort, table.getn
local ceil = math.ceil
--WoW API / Variables
local GetTime = GetTime
local CreateFrame = CreateFrame
local IsShiftKeyDown = IsShiftKeyDown
local IsAltKeyDown = IsAltKeyDown
local IsControlKeyDown = IsControlKeyDown
local UnitCanAttack = UnitCanAttack
local UnitIsFriend = UnitIsFriend
local UnitIsUnit = UnitIsUnit
function UF:Construct_Buffs(frame)
local buffs = CreateFrame("Frame", frame:GetName().."Buffs", frame)
buffs.spacing = E.Spacing
buffs.PreSetPosition = (not frame:GetScript("OnUpdate")) and self.SortAuras or nil
buffs.PostCreateIcon = self.Construct_AuraIcon
buffs.PostUpdateIcon = self.PostUpdateAura
buffs.CustomFilter = self.AuraFilter
buffs:SetFrameLevel(frame.RaisedElementParent:GetFrameLevel() + 10) --Make them appear above any text element
buffs.type = "buffs"
--Set initial width to prevent division by zero. This value doesn't matter, as it will be updated later
buffs:Width(100)
return buffs
end
function UF:Construct_Debuffs(frame)
local debuffs = CreateFrame("Frame", frame:GetName().."Debuffs", frame)
debuffs.spacing = E.Spacing
debuffs.PreSetPosition = (not frame:GetScript("OnUpdate")) and self.SortAuras or nil
debuffs.PostCreateIcon = self.Construct_AuraIcon
debuffs.PostUpdateIcon = self.PostUpdateAura
debuffs.CustomFilter = self.AuraFilter
debuffs.type = "debuffs"
debuffs:SetFrameLevel(frame.RaisedElementParent:GetFrameLevel() + 10) --Make them appear above any text element
--Set initial width to prevent division by zero. This value doesn't matter, as it will be updated later
debuffs:Width(100)
return debuffs
end
function UF:Construct_AuraIcon(button)
local offset = UF.thinBorders and E.mult or E.Border
button.text = button.cd:CreateFontString(nil, "OVERLAY")
button.text:Point("CENTER", 1, 1)
button.text:SetJustifyH("CENTER")
button:SetTemplate("Default", nil, nil, UF.thinBorders, true)
button.cd.noOCC = true
button.cd.noCooldownCount = true
button.cd:SetReverse(true)
button.cd:SetDrawEdge(true)
button.cd:SetInside(button, offset, offset)
button.icon:SetInside(button, offset, offset)
button.icon:SetTexCoord(unpack(E.TexCoords))
button.icon:SetDrawLayer("ARTWORK")
button.count:ClearAllPoints()
button.count:Point("BOTTOMRIGHT", 1, 1)
button.count:SetJustifyH("RIGHT")
button.overlay:SetTexture(nil)
button.stealable:SetTexture(nil)
button:RegisterForClicks("RightButtonUp")
button:SetScript("OnClick", function(self)
if E.db.unitframe.auraBlacklistModifier == "NONE" or not ((E.db.unitframe.auraBlacklistModifier == "SHIFT" and IsShiftKeyDown()) or (E.db.unitframe.auraBlacklistModifier == "ALT" and IsAltKeyDown()) or (E.db.unitframe.auraBlacklistModifier == "CTRL" and IsControlKeyDown())) then return; end
local auraName = self.name
if auraName then
E:Print(format(L["The spell '%s' has been added to the Blacklist unitframe aura filter."], auraName))
E.global["unitframe"]["aurafilters"]["Blacklist"]["spells"][auraName] = {
["enable"] = true,
["priority"] = 0,
}
UF:Update_AllFrames()
end
end)
UF:UpdateAuraIconSettings(button, true)
end
function UF:EnableDisable_Auras(frame)
if frame.db.debuffs.enable or frame.db.buffs.enable then
if not frame:IsElementEnabled("Aura") then
frame:EnableElement("Aura")
end
else
if frame:IsElementEnabled("Aura") then
frame:DisableElement("Aura")
end
end
end
local function ReverseUpdate(frame)
UF:Configure_Auras(frame, "Debuffs")
UF:Configure_Auras(frame, "Buffs")
end
function UF:Configure_Auras(frame, auraType)
if not frame.VARIABLES_SET then return end
local db = frame.db
local auras = frame[auraType]
auraType = auraType:lower()
local rows = db[auraType].numrows
local totalWidth = frame.UNIT_WIDTH - frame.SPACING*2
if frame.USE_POWERBAR_OFFSET then
local powerOffset = ((frame.ORIENTATION == "MIDDLE" and 2 or 1) * frame.POWERBAR_OFFSET)
if not (db[auraType].attachTo == "POWER" and frame.ORIENTATION == "MIDDLE") then
totalWidth = totalWidth - powerOffset
end
end
auras:Width(totalWidth)
auras.forceShow = frame.forceShowAuras
auras.num = db[auraType].perrow * rows
auras.size = db[auraType].sizeOverride ~= 0 and db[auraType].sizeOverride or ((((auras:GetWidth() - (auras.spacing*(auras.num/rows - 1))) / auras.num)) * rows)
if db[auraType].sizeOverride and db[auraType].sizeOverride > 0 then
auras:Width(db[auraType].perrow * db[auraType].sizeOverride)
end
local attachTo = self:GetAuraAnchorFrame(frame, db[auraType].attachTo, db.debuffs.attachTo == "BUFFS" and db.buffs.attachTo == "DEBUFFS")
local x, y = E:GetXYOffset(db[auraType].anchorPoint, frame.SPACING) --Use frame.SPACING override since it may be different from E.Spacing due to forced thin borders
if db[auraType].attachTo == "FRAME" then
y = 0
elseif db[auraType].attachTo == "HEALTH" or db[auraType].attachTo == "POWER" then
local newX = E:GetXYOffset(db[auraType].anchorPoint, -frame.BORDER)
local _, newY = E:GetXYOffset(db[auraType].anchorPoint, (frame.BORDER + frame.SPACING))
x = newX
y = newY
else
x = 0
end
if (auraType == "buffs" and frame.Debuffs.attachTo and frame.Debuffs.attachTo == frame.Buffs and db[auraType].attachTo == "DEBUFFS") then
--Update Debuffs first, as we would otherwise get conflicting anchor points
--This is usually only an issue on profile change
ReverseUpdate(frame)
return
end
auras:ClearAllPoints()
auras:Point(E.InversePoints[db[auraType].anchorPoint], attachTo, db[auraType].anchorPoint, x + db[auraType].xOffset, y + db[auraType].yOffset)
auras:Height(auras.size * rows)
auras["growth-y"] = find(db[auraType].anchorPoint, "TOP") and "UP" or "DOWN"
auras["growth-x"] = db[auraType].anchorPoint == "LEFT" and "LEFT" or db[auraType].anchorPoint == "RIGHT" and "RIGHT" or (find(db[auraType].anchorPoint, "LEFT") and "RIGHT" or "LEFT")
auras.initialAnchor = E.InversePoints[db[auraType].anchorPoint]
--These are needed for SmartAuraPosition
auras.attachTo = attachTo
auras.point = E.InversePoints[db[auraType].anchorPoint]
auras.anchorPoint = db[auraType].anchorPoint
auras.xOffset = x + db[auraType].xOffset
auras.yOffset = y + db[auraType].yOffset
if db[auraType].enable then
auras:Show()
UF:UpdateAuraIconSettings(auras)
else
auras:Hide()
end
local position = db.smartAuraPosition
if position == "BUFFS_ON_DEBUFFS" then
if db.debuffs.attachTo == "BUFFS" then
E:Print(format(L["This setting caused a conflicting anchor point, where '%s' would be attached to itself. Please check your anchor points. Setting '%s' to be attached to '%s'."], L["Buffs"], L["Debuffs"], L["Frame"]))
db.debuffs.attachTo = "FRAME"
frame.Debuffs.attachTo = frame
end
frame.Buffs.PostUpdate = nil
frame.Debuffs.PostUpdate = UF.UpdateBuffsHeaderPosition
elseif position == "DEBUFFS_ON_BUFFS" then
if db.buffs.attachTo == "DEBUFFS" then
E:Print(format(L["This setting caused a conflicting anchor point, where '%s' would be attached to itself. Please check your anchor points. Setting '%s' to be attached to '%s'."], L["Debuffs"], L["Buffs"], L["Frame"]))
db.buffs.attachTo = "FRAME"
frame.Buffs.attachTo = frame
end
frame.Buffs.PostUpdate = UF.UpdateDebuffsHeaderPosition
frame.Debuffs.PostUpdate = nil
elseif position == "FLUID_BUFFS_ON_DEBUFFS" then
if db.debuffs.attachTo == "BUFFS" then
E:Print(format(L["This setting caused a conflicting anchor point, where '%s' would be attached to itself. Please check your anchor points. Setting '%s' to be attached to '%s'."], L["Buffs"], L["Debuffs"], L["Frame"]))
db.debuffs.attachTo = "FRAME"
frame.Debuffs.attachTo = frame
end
frame.Buffs.PostUpdate = UF.UpdateBuffsHeight
frame.Debuffs.PostUpdate = UF.UpdateBuffsPositionAndDebuffHeight
elseif position == "FLUID_DEBUFFS_ON_BUFFS" then
if db.buffs.attachTo == "DEBUFFS" then
E:Print(format(L["This setting caused a conflicting anchor point, where '%s' would be attached to itself. Please check your anchor points. Setting '%s' to be attached to '%s'."], L["Debuffs"], L["Buffs"], L["Frame"]))
db.buffs.attachTo = "FRAME"
frame.Buffs.attachTo = frame
end
frame.Buffs.PostUpdate = UF.UpdateDebuffsPositionAndBuffHeight
frame.Debuffs.PostUpdate = UF.UpdateDebuffsHeight
else
frame.Buffs.PostUpdate = nil
frame.Debuffs.PostUpdate = nil
end
end
local function SortAurasByTime(a, b)
if (a and b and a:GetParent().db) then
if a:IsShown() and b:IsShown() then
local sortDirection = a:GetParent().db.sortDirection
local aTime = a.expiration or -1
local bTime = b.expiration or -1
if (aTime and bTime) then
if(sortDirection == "DESCENDING") then
return aTime < bTime
else
return aTime > bTime
end
end
elseif a:IsShown() then
return true
end
end
end
local function SortAurasByName(a, b)
if (a and b and a:GetParent().db) then
if a:IsShown() and b:IsShown() then
local sortDirection = a:GetParent().db.sortDirection
local aName = a.spell or ""
local bName = b.spell or ""
if (aName and bName) then
if(sortDirection == "DESCENDING") then
return aName < bName
else
return aName > bName
end
end
elseif a:IsShown() then
return true
end
end
end
local function SortAurasByDuration(a, b)
if (a and b and a:GetParent().db) then
if a:IsShown() and b:IsShown() then
local sortDirection = a:GetParent().db.sortDirection
local aTime = a.duration or -1
local bTime = b.duration or -1
if (aTime and bTime) then
if(sortDirection == "DESCENDING") then
return aTime < bTime
else
return aTime > bTime
end
end
elseif a:IsShown() then
return true
end
end
end
local function SortAurasByCaster(a, b)
if (a and b and a:GetParent().db) then
if a:IsShown() and b:IsShown() then
local sortDirection = a:GetParent().db.sortDirection
local aPlayer = a.isPlayer or false
local bPlayer = b.isPlayer or false
if(sortDirection == "DESCENDING") then
return (aPlayer and not bPlayer)
else
return (not aPlayer and bPlayer)
end
elseif a:IsShown() then
return true
end
end
end
function UF:SortAuras()
if not self.db then return end
--Sorting by Index is Default
if(self.db.sortMethod == "TIME_REMAINING") then
tsort(self, SortAurasByTime)
elseif(self.db.sortMethod == "NAME") then
tsort(self, SortAurasByName)
elseif(self.db.sortMethod == "DURATION") then
tsort(self, SortAurasByDuration)
elseif (self.db.sortMethod == "PLAYER") then
tsort(self, SortAurasByCaster)
end
--Look into possibly applying filter priorities for auras here.
return 1, getn(self) --from/to range needed for the :SetPosition call in oUF aura element. Without this aura icon position gets all whacky when not sorted by index
end
function UF:UpdateAuraIconSettings(auras, noCycle)
local frame = auras:GetParent()
local type = auras.type
if(noCycle) then
frame = auras:GetParent():GetParent()
type = auras:GetParent().type
end
if(not frame.db) then return end
local db = frame.db[type]
local unitframeFont = LSM:Fetch("font", E.db["unitframe"].font)
local unitframeFontOutline = E.db["unitframe"].fontOutline
local index = 1
auras.db = db
if(db) then
if(not noCycle) then
while(auras[index]) do
local button = auras[index]
button.text:FontTemplate(unitframeFont, db.fontSize, unitframeFontOutline)
button.count:FontTemplate(unitframeFont, db.countFontSize or db.fontSize, unitframeFontOutline)
if db.clickThrough and button:IsMouseEnabled() then
button:EnableMouse(false)
elseif not db.clickThrough and not button:IsMouseEnabled() then
button:EnableMouse(true)
end
index = index + 1
end
else
auras.text:FontTemplate(unitframeFont, db.fontSize, unitframeFontOutline)
auras.count:FontTemplate(unitframeFont, db.countFontSize or db.fontSize, unitframeFontOutline)
if db.clickThrough and auras:IsMouseEnabled() then
auras:EnableMouse(false)
elseif not db.clickThrough and not auras:IsMouseEnabled() then
auras:EnableMouse(true)
end
end
end
end
local unstableAffliction = GetSpellInfo(30108)
local vampiricTouch = GetSpellInfo(34914)
function UF:PostUpdateAura(unit, button)
local auras = button:GetParent()
local frame = auras:GetParent()
local type = auras.type
local db = frame.db and frame.db[type]
if db then
if db.clickThrough and button:IsMouseEnabled() then
button:EnableMouse(false)
elseif not db.clickThrough and not button:IsMouseEnabled() then
button:EnableMouse(true)
end
end
if button.isDebuff then
if(not button.isFriend and not button.isPlayer) then --[[and (not E.isDebuffWhiteList[name])]]
button:SetBackdropBorderColor(0.9, 0.1, 0.1)
button.icon:SetDesaturated((unit and not find(unit, "arena%d")) and true or false)
else
local color = (button.dtype and DebuffTypeColor[button.dtype]) or DebuffTypeColor.none
if button.name and (button.name == unstableAffliction or button.name == vampiricTouch) and E.myclass ~= "WARLOCK" then
button:SetBackdropBorderColor(0.05, 0.85, 0.94)
else
button:SetBackdropBorderColor(color.r * 0.6, color.g * 0.6, color.b * 0.6)
end
button.icon:SetDesaturated(false)
end
else
if button.isStealable and not button.isFriend then
button:SetBackdropBorderColor(237/255, 234/255, 142/255)
else
button:SetBackdropBorderColor(unpack(E["media"].unitframeBorderColor))
end
end
local size = button:GetParent().size
if size then
button:SetSize(size, size)
end
if button.expiration and button.duration and (button.duration ~= 0) then
local getTime = GetTime()
if not button:GetScript("OnUpdate") then
button.expirationTime = button.expiration
button.expirationSaved = button.expiration - getTime
button.nextupdate = -1
button:SetScript("OnUpdate", UF.UpdateAuraTimer)
end
if (button.expirationTime ~= button.expiration) or (button.expirationSaved ~= (button.expiration - getTime)) then
button.expirationTime = button.expiration
button.expirationSaved = button.expiration - getTime
button.nextupdate = -1
end
end
if button.expiration and button.duration and (button.duration == 0 or button.expiration <= 0) then
button.expirationTime = nil
button.expirationSaved = nil
button:SetScript("OnUpdate", nil)
if button.text:GetFont() then
button.text:SetText("")
end
end
end
function UF:UpdateAuraTimer(elapsed)
self.expirationSaved = self.expirationSaved - elapsed
if self.nextupdate > 0 then
self.nextupdate = self.nextupdate - elapsed
return
end
if self.expirationSaved <= 0 then
self:SetScript("OnUpdate", nil)
if(self.text:GetFont()) then
self.text:SetText("")
end
return
end
local timervalue, formatid
timervalue, formatid, self.nextupdate = E:GetTimeInfo(self.expirationSaved, 4)
if self.text:GetFont() then
self.text:SetFormattedText(format("%s%s|r", E.TimeColors[formatid], E.TimeFormats[formatid][2]), timervalue)
elseif self:GetParent():GetParent().db then
self.text:FontTemplate(LSM:Fetch("font", E.db["unitframe"].font), self:GetParent():GetParent().db[self:GetParent().type].fontSize, E.db["unitframe"].fontOutline)
self.text:SetFormattedText(format("%s%s|r", E.TimeColors[formatid], E.TimeFormats[formatid][2]), timervalue)
end
end
function UF:AuraFilter(unit, button, name, _, _, _, dispelType, duration, expiration, caster, isStealable, _, spellID)
local db = self:GetParent().db
if not db or not db[self.type] then return true; end
db = db[self.type]
if not name then return nil end
local filterCheck, isUnit, isFriend, isPlayer, canDispell, allowDuration, noDuration, spellPriority
isPlayer = (caster == "player" or caster == "vehicle")
isFriend = unit and UnitIsFriend("player", unit) and not UnitCanAttack("player", unit)
button.isPlayer = isPlayer
button.isFriend = isFriend
button.isStealable = isStealable
button.dtype = dispelType
button.duration = duration
button.expiration = expiration
button.name = name
button.owner = caster --what uses this?
button.spell = name --what uses this? (SortAurasByName?)
button.priority = 0
noDuration = (not duration or duration == 0)
allowDuration = noDuration or (duration and (duration > 0) and (db.maxDuration == 0 or duration <= db.maxDuration) and (db.minDuration == 0 or duration >= db.minDuration))
if db.priority ~= "" then
isUnit = unit and caster and UnitIsUnit(unit, caster)
canDispell = (self.type == "buffs" and isStealable) or (self.type == "debuffs" and dispelType and E:IsDispellableByMe(dispelType))
filterCheck, spellPriority = UF:CheckFilter(name, caster, spellID, isFriend, isPlayer, isUnit, allowDuration, noDuration, canDispell, strsplit(",", db.priority))
if spellPriority then button.priority = spellPriority end -- this is the only difference from auarbars code
else
filterCheck = allowDuration and true -- Allow all auras to be shown when the filter list is empty, while obeying duration sliders
end
return filterCheck
end
function UF:UpdateBuffsHeaderPosition()
local parent = self:GetParent()
local buffs = parent.Buffs
local debuffs = parent.Debuffs
local numDebuffs = self.visibleDebuffs
if numDebuffs == 0 then
buffs:ClearAllPoints()
buffs:Point(debuffs.point, debuffs.attachTo, debuffs.anchorPoint, debuffs.xOffset, debuffs.yOffset)
else
buffs:ClearAllPoints()
buffs:Point(buffs.point, buffs.attachTo, buffs.anchorPoint, buffs.xOffset, buffs.yOffset)
end
end
function UF:UpdateDebuffsHeaderPosition()
local parent = self:GetParent()
local debuffs = parent.Debuffs
local buffs = parent.Buffs
local numBuffs = self.visibleBuffs
if numBuffs == 0 then
debuffs:ClearAllPoints()
debuffs:Point(buffs.point, buffs.attachTo, buffs.anchorPoint, buffs.xOffset, buffs.yOffset)
else
debuffs:ClearAllPoints()
debuffs:Point(debuffs.point, debuffs.attachTo, debuffs.anchorPoint, debuffs.xOffset, debuffs.yOffset)
end
end
function UF:UpdateBuffsPositionAndDebuffHeight()
local parent = self:GetParent()
local db = parent.db
local buffs = parent.Buffs
local debuffs = parent.Debuffs
local numDebuffs = self.visibleDebuffs
if numDebuffs == 0 then
buffs:ClearAllPoints()
buffs:Point(debuffs.point, debuffs.attachTo, debuffs.anchorPoint, debuffs.xOffset, debuffs.yOffset)
else
buffs:ClearAllPoints()
buffs:Point(buffs.point, buffs.attachTo, buffs.anchorPoint, buffs.xOffset, buffs.yOffset)
end
if numDebuffs > 0 then
local numRows = ceil(numDebuffs/db.debuffs.perrow)
debuffs:Height(debuffs.size * (numRows > db.debuffs.numrows and db.debuffs.numrows or numRows))
else
debuffs:Height(debuffs.size)
end
end
function UF:UpdateDebuffsPositionAndBuffHeight()
local parent = self:GetParent()
local db = parent.db
local debuffs = parent.Debuffs
local buffs = parent.Buffs
local numBuffs = self.visibleBuffs
if numBuffs == 0 then
debuffs:ClearAllPoints()
debuffs:Point(buffs.point, buffs.attachTo, buffs.anchorPoint, buffs.xOffset, buffs.yOffset)
else
debuffs:ClearAllPoints()
debuffs:Point(debuffs.point, debuffs.attachTo, debuffs.anchorPoint, debuffs.xOffset, debuffs.yOffset)
end
if numBuffs > 0 then
local numRows = ceil(numBuffs/db.buffs.perrow)
buffs:Height(buffs.size * (numRows > db.buffs.numrows and db.buffs.numrows or numRows))
else
buffs:Height(buffs.size)
end
end
function UF:UpdateBuffsHeight()
local parent = self:GetParent()
local db = parent.db
local buffs = parent.Buffs
local numBuffs = self.visibleBuffs
if numBuffs > 0 then
local numRows = ceil(numBuffs/db.buffs.perrow)
buffs:Height(buffs.size * (numRows > db.buffs.numrows and db.buffs.numrows or numRows))
else
buffs:Height(buffs.size)
-- Any way to get rid of the last row as well?
-- Using buffs:SetHeight(0) makes frames anchored to this one disappear
end
end
function UF:UpdateDebuffsHeight()
local parent = self:GetParent()
local db = parent.db
local debuffs = parent.Debuffs
local numDebuffs = self.visibleDebuffs
if numDebuffs > 0 then
local numRows = ceil(numDebuffs/db.debuffs.perrow)
debuffs:Height(debuffs.size * (numRows > db.debuffs.numrows and db.debuffs.numrows or numRows))
else
debuffs:Height(debuffs.size)
-- Any way to get rid of the last row as well?
-- Using debuffs:SetHeight(0) makes frames anchored to this one disappear
end
end
@@ -1,4 +1,5 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/"> <Ui xmlns="http://www.blizzard.com/wow/ui/">
<Script file="Auras.lua"/>
<Script file="CombatIndicator.lua"/> <Script file="CombatIndicator.lua"/>
<Script file="Health.lua"/> <Script file="Health.lua"/>
<Script file="Name.lua"/> <Script file="Name.lua"/>