PageRenderTime 145ms CodeModel.GetById 81ms app.highlight 15ms RepoModel.GetById 45ms app.codeStats 0ms

/Tukui/modules/unitframes/core/oUF/elements/aura.lua

http://github.com/Asphyxia/Tukui
Lua | 295 lines | 229 code | 62 blank | 4 comment | 46 complexity | 8405a5fa5be28517f36feb3dd103f6e2 MD5 | raw file
  1local parent, ns = ...
  2local oUF = ns.oUF
  3
  4local VISIBLE = 1
  5local HIDDEN = 0
  6
  7local UpdateTooltip = function(self)
  8	GameTooltip:SetUnitAura(self.parent.__owner.unit, self:GetID(), self.filter)
  9end
 10
 11local OnEnter = function(self)
 12	if(not self:IsVisible()) then return end
 13
 14	GameTooltip:SetOwner(self, "ANCHOR_BOTTOMRIGHT")
 15	self:UpdateTooltip()
 16end
 17
 18local OnLeave = function()
 19	GameTooltip:Hide()
 20end
 21
 22local createAuraIcon = function(icons, index)
 23	local button = CreateFrame("Button", nil, icons)
 24	button:EnableMouse(true)
 25	button:RegisterForClicks'RightButtonUp'
 26
 27	button:SetWidth(icons.size or 16)
 28	button:SetHeight(icons.size or 16)
 29
 30	local cd = CreateFrame("Cooldown", nil, button)
 31	cd:SetAllPoints(button)
 32
 33	local icon = button:CreateTexture(nil, "BORDER")
 34	icon:SetAllPoints(button)
 35
 36	local count = button:CreateFontString(nil, "OVERLAY")
 37	count:SetFontObject(NumberFontNormal)
 38	count:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -1, 0)
 39
 40	local overlay = button:CreateTexture(nil, "OVERLAY")
 41	overlay:SetTexture"Interface\\Buttons\\UI-Debuff-Overlays"
 42	overlay:SetAllPoints(button)
 43	overlay:SetTexCoord(.296875, .5703125, 0, .515625)
 44	button.overlay = overlay
 45
 46	local stealable = button:CreateTexture(nil, 'OVERLAY')
 47	stealable:SetTexture[[Interface\TargetingFrame\UI-TargetingFrame-Stealable]]
 48	stealable:SetPoint('TOPLEFT', -3, 3)
 49	stealable:SetPoint('BOTTOMRIGHT', 3, -3)
 50	stealable:SetBlendMode'ADD'
 51	button.stealable = stealable
 52
 53	button.UpdateTooltip = UpdateTooltip
 54	button:SetScript("OnEnter", OnEnter)
 55	button:SetScript("OnLeave", OnLeave)
 56
 57	table.insert(icons, button)
 58
 59	button.parent = icons
 60	button.icon = icon
 61	button.count = count
 62	button.cd = cd
 63
 64	if(icons.PostCreateIcon) then icons:PostCreateIcon(button) end
 65
 66	return button
 67end
 68
 69local customFilter = function(icons, unit, icon, name, rank, texture, count, dtype, duration, timeLeft, caster)
 70	local isPlayer
 71
 72	if(caster == 'player' or caster == 'vehicle') then
 73		isPlayer = true
 74	end
 75
 76	if((icons.onlyShowPlayer and isPlayer) or (not icons.onlyShowPlayer and name)) then
 77		icon.isPlayer = isPlayer
 78		icon.owner = caster
 79		return true
 80	end
 81end
 82
 83local updateIcon = function(unit, icons, index, offset, filter, isDebuff, visible)
 84	local name, rank, texture, count, dtype, duration, timeLeft, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff = UnitAura(unit, index, filter)
 85	if(name) then
 86		local n = visible + offset + 1
 87		local icon = icons[n]
 88		if(not icon) then
 89			icon = (icons.CreateIcon or createAuraIcon) (icons, n)
 90		end
 91
 92		local show = (icons.CustomFilter or customFilter) (icons, unit, icon, name, rank, texture, count, dtype, duration, timeLeft, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff)
 93		if(show) then
 94			-- We might want to consider delaying the creation of an actual cooldown
 95			-- object to this point, but I think that will just make things needlessly
 96			-- complicated.
 97			local cd = icon.cd
 98			if(cd and not icons.disableCooldown) then
 99				if(duration and duration > 0) then
100					cd:SetCooldown(timeLeft - duration, duration)
101					cd:Show()
102				else
103					cd:Hide()
104				end
105			end
106
107			if((isDebuff and icons.showDebuffType) or (not isDebuff and icons.showBuffType) or icons.showType) then
108				local color = DebuffTypeColor[dtype] or DebuffTypeColor.none
109
110				icon.overlay:SetVertexColor(color.r, color.g, color.b)
111				icon.overlay:Show()
112			else
113				icon.overlay:Hide()
114			end
115
116			-- XXX: Avoid popping errors on layouts without icon.stealable.
117			if(icon.stealable) then
118				local stealable = not isDebuff and isStealable
119				if(stealable and icons.showStealableBuffs and not UnitIsUnit('player', unit)) then
120					icon.stealable:Show()
121				else
122					icon.stealable:Hide()
123				end
124			end
125
126			icon.icon:SetTexture(texture)
127			icon.count:SetText((count > 1 and count))
128
129			icon.filter = filter
130			icon.debuff = isDebuff
131
132			icon:SetID(index)
133			icon:Show()
134
135			if(icons.PostUpdateIcon) then
136				icons:PostUpdateIcon(unit, icon, index, offset)
137			end
138
139			return VISIBLE
140		else
141			return HIDDEN
142		end
143	end
144end
145
146local SetPosition = function(icons, x)
147	if(icons and x > 0) then
148		local col = 0
149		local row = 0
150		local gap = icons.gap
151		local sizex = (icons.size or 16) + (icons['spacing-x'] or icons.spacing or 0)
152		local sizey = (icons.size or 16) + (icons['spacing-y'] or icons.spacing or 0)
153		local anchor = icons.initialAnchor or "BOTTOMLEFT"
154		local growthx = (icons["growth-x"] == "LEFT" and -1) or 1
155		local growthy = (icons["growth-y"] == "DOWN" and -1) or 1
156		local cols = math.floor(icons:GetWidth() / sizex + .5)
157		local rows = math.floor(icons:GetHeight() / sizey + .5)
158
159		for i = 1, #icons do
160			local button = icons[i]
161			if(button and button:IsShown()) then
162				if(gap and button.debuff) then
163					if(col > 0) then
164						col = col + 1
165					end
166
167					gap = false
168				end
169
170				if(col >= cols) then
171					col = 0
172					row = row + 1
173				end
174				button:ClearAllPoints()
175				button:SetPoint(anchor, icons, anchor, col * sizex * growthx, row * sizey * growthy)
176
177				col = col + 1
178			elseif(not button) then
179				break
180			end
181		end
182	end
183end
184
185local filterIcons = function(unit, icons, filter, limit, isDebuff, offset, dontHide)
186	if(not offset) then offset = 0 end
187	local index = 1
188	local visible = 0
189	while(visible < limit) do
190		local result = updateIcon(unit, icons, index, offset, filter, isDebuff, visible)
191		if(not result) then
192			break
193		elseif(result == VISIBLE) then
194			visible = visible + 1
195		end
196
197		index = index + 1
198	end
199
200	if(not dontHide) then
201		for i = visible + offset + 1, #icons do
202			icons[i]:Hide()
203		end
204	end
205
206	return visible
207end
208
209local Update = function(self, event, unit)
210	if(self.unit ~= unit) then return end
211
212	local auras = self.Auras
213	if(auras) then
214		if(auras.PreUpdate) then auras:PreUpdate(unit) end
215
216		local numBuffs = auras.numBuffs or 32
217		local numDebuffs = auras.numDebuffs or 40
218		local max = numBuffs + numDebuffs
219
220		local visibleBuffs = filterIcons(unit, auras, auras.buffFilter or auras.filter or 'HELPFUL', numBuffs, nil, 0, true)
221		auras.visibleBuffs = visibleBuffs
222
223		auras.visibleDebuffs = filterIcons(unit, auras, auras.debuffFilter or auras.filter or 'HARMFUL', numDebuffs, true, visibleBuffs)
224		auras.visibleAuras = auras.visibleBuffs + auras.visibleDebuffs
225
226		if(auras.PreSetPosition) then auras:PreSetPosition(max) end
227		(auras.SetPosition or SetPosition) (auras, max)
228
229		if(auras.PostUpdate) then auras:PostUpdate(unit) end
230	end
231
232	local buffs = self.Buffs
233	if(buffs) then
234		if(buffs.PreUpdate) then buffs:PreUpdate(unit) end
235
236		local numBuffs = buffs.num or 32
237		buffs.visibleBuffs = filterIcons(unit, buffs, buffs.filter or 'HELPFUL', numBuffs)
238
239		if(buffs.PreSetPosition) then buffs:PreSetPosition(numBuffs) end
240		(buffs.SetPosition or SetPosition) (buffs, numBuffs)
241
242		if(buffs.PostUpdate) then buffs:PostUpdate(unit) end
243	end
244
245	local debuffs = self.Debuffs
246	if(debuffs) then
247		if(debuffs.PreUpdate) then debuffs:PreUpdate(unit) end
248
249		local numDebuffs = debuffs.num or 40
250		debuffs.visibleDebuffs = filterIcons(unit, debuffs, debuffs.filter or 'HARMFUL', numDebuffs, true)
251
252		if(debuffs.PreSetPosition) then debuffs:PreSetPosition(numDebuffs) end
253		(debuffs.SetPosition or SetPosition) (debuffs, numDebuffs)
254
255		if(debuffs.PostUpdate) then debuffs:PostUpdate(unit) end
256	end
257end
258
259local ForceUpdate = function(element)
260	return Update(element.__owner, 'ForceUpdate', element.__owner.unit)
261end
262
263local Enable = function(self)
264	if(self.Buffs or self.Debuffs or self.Auras) then
265		self:RegisterEvent("UNIT_AURA", Update)
266
267		local buffs = self.Buffs
268		if(buffs) then
269			buffs.__owner = self
270			buffs.ForceUpdate = ForceUpdate
271		end
272
273		local debuffs = self.Debuffs
274		if(debuffs) then
275			debuffs.__owner = self
276			debuffs.ForceUpdate = ForceUpdate
277		end
278
279		local auras = self.Auras
280		if(auras) then
281			auras.__owner = self
282			auras.ForceUpdate = ForceUpdate
283		end
284
285		return true
286	end
287end
288
289local Disable = function(self)
290	if(self.Buffs or self.Debuffs or self.Auras) then
291		self:UnregisterEvent("UNIT_AURA", Update)
292	end
293end
294
295oUF:AddElement('Aura', Update, Enable, Disable)