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

http://github.com/Ekst/Tukui · Lua · 295 lines · 283 code · 12 blank · 0 comment · 3 complexity · cef0655273d23ab3d16e035756975294 MD5 · raw file

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