Mercurial > wow > buffalo2
comparison BuffButton.lua @ 0:3dbcad2b387d
initial push
| author | Nenue |
|---|---|
| date | Wed, 30 Mar 2016 02:24:56 -0400 |
| parents | |
| children | b0447b382f36 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:3dbcad2b387d |
|---|---|
| 1 --- Actual BlizzUI modifications are applied here | |
| 2 -- @file-author@ | |
| 3 -- @project-revision@ @project-hash@ | |
| 4 -- @file-revision@ @file-hash@ | |
| 5 -- Created: 3/12/2016 12:47 AM | |
| 6 local MODULE = 'BuffFrame' | |
| 7 local _, A = ... | |
| 8 local B, _G = A.frame, _G | |
| 9 local type, unpack, select, pairs, ipairs = _G.type, _G.unpack, _G.select, _G.pairs, _G.ipairs | |
| 10 local min, ceil, mod, tonumber, tostring = _G.min, _G.ceil, _G.mod, _G.tonumber, _G.tostring | |
| 11 local floor, wipe, max = _G.math.floor, _G.table.wipe, _G.math.max | |
| 12 local CreateFrame, IsInGroup, GetCVarBool = _G.CreateFrame, _G.IsInGroup, _G.GetCVarBool | |
| 13 local BuffFrame, ConsolidatedBuffs = _G.BuffFrame, _G.ConsolidatedBuffs | |
| 14 local print, gprint, aprint, fprint = B.print('Buff'), B.print('SetGuides'), B.print('SetAnchors'), B.fprint | |
| 15 local displays, anchors, guides, decors, positioned, drawn, zoom = B.displays, {}, {}, {}, {}, {}, {} | |
| 16 local UnitAura, UnitName, RegisterStateDriver = _G.UnitAura, _G.UnitName, _G.RegisterStateDriver | |
| 17 | |
| 18 local M = B:RegisterModule(MODULE) | |
| 19 | |
| 20 M.GetBuffZoom = function(buffName) | |
| 21 local zoom = tonumber(B.displays[buffName].conf['Zoom']) / 100 / 2 | |
| 22 local zoomL, zoomU, zoomR, zoomD = zoom, zoom, 1-zoom, 1-zoom | |
| 23 print(buffName, zoom) | |
| 24 return function(self, ...) | |
| 25 if select('#',...) == 4 then | |
| 26 zoomL, zoomR, zoomU, zoomD = ... | |
| 27 end | |
| 28 self:SetTexCoord(zoomL, zoomR, zoomU, zoomD) | |
| 29 return zoomL, zoomR, zoomU, zoomD | |
| 30 end | |
| 31 end | |
| 32 | |
| 33 | |
| 34 | |
| 35 M.UpdateButtonAlpha = function(self) | |
| 36 if not self.parent.timeLeft or not self:IsVisible() then | |
| 37 self:SetScript('OnUpdate', nil) | |
| 38 return | |
| 39 end | |
| 40 | |
| 41 if self.parent.timeLeft < _G.BUFF_WARNING_TIME then | |
| 42 self:SetAlpha(BuffFrame.BuffAlphaValue) | |
| 43 else | |
| 44 self:SetAlpha(1) | |
| 45 end | |
| 46 end | |
| 47 | |
| 48 --- Called infrequently to align stencil frames | |
| 49 local refreshCount = 0 | |
| 50 M.UpdateGuideFrames = function(buffName) | |
| 51 refreshCount = refreshCount + 1 | |
| 52 local print = fprint() | |
| 53 | |
| 54 | |
| 55 local anchor = anchors[buffName] | |
| 56 local c, g, d = displays[buffName].conf, guides[buffName], decors[buffName] | |
| 57 local perRow = c['PerRow'] | |
| 58 local buffSpacing, buffSize, buffBorder, buffDurationSize, buffCountSize, relativeX, relativeY = c['Spacing'], c['Size'], c['Border'], c['DurationSize'], c['CountSize'], c['RelativeX'], c['RelativeY'] | |
| 59 local consolidated = (anchors[buffName].contains and IsInGroup()) | |
| 60 local consolidatedPosition = (consolidated and anchors[buffName].containPosition or 0) | |
| 61 | |
| 62 | |
| 63 print('|cFF00FF00Setting Guides ('..refreshCount..'):|r', buffName, 'user max:',c['Max'], 'hard max:', displays[buffName].maxIcons) | |
| 64 | |
| 65 local buffMax = min(c['Max'], displays[buffName].maxIcons) | |
| 66 local anchorFrom, anchorTo = c.Point[1], c.Point[2] | |
| 67 anchor.Zoom = M.GetBuffZoom(buffName) | |
| 68 | |
| 69 | |
| 70 | |
| 71 if consolidated then | |
| 72 buffMax = buffMax + 1 | |
| 73 end | |
| 74 | |
| 75 local legend = {} | |
| 76 legend.r, legend.g, legend.b, legend.a = unpack(displays[buffName].legendColor) | |
| 77 local horizFrom = (relativeX < 0) and 'RIGHT' or 'LEFT' | |
| 78 local horizTo = (relativeX < 0) and 'LEFT' or 'RIGHT' | |
| 79 local vertFrom = (relativeY < 0) and 'TOP' or 'BOTTOM' | |
| 80 local vertTo = (relativeY < 0) and 'BOTTOM' or 'TOP' | |
| 81 local previous, up | |
| 82 local bottom_extent = 0 | |
| 83 for i = 1, buffMax do | |
| 84 print('update idx', i) | |
| 85 if not g[i] then | |
| 86 g[i] = CreateFrame('Frame', buffName..'Guide'..i, anchor, displays[buffName].template or 'VeneerGuideTemplate') | |
| 87 RegisterStateDriver(g[i], "visibility", "[petbattle] [vehicleui] hide; show") | |
| 88 end | |
| 89 | |
| 90 local guide = g[i] | |
| 91 | |
| 92 local row = ceil(i / perRow) | |
| 93 local col = mod(i, perRow) | |
| 94 if col == 0 then | |
| 95 col = perRow | |
| 96 end | |
| 97 | |
| 98 guide.previous = previous | |
| 99 guide.up = up | |
| 100 local x, y, parent = 0, 0, anchor | |
| 101 if i == 1 then | |
| 102 parent = anchor | |
| 103 up = guide | |
| 104 elseif col == 1 then | |
| 105 parent = g[i-perRow] | |
| 106 y = (buffSpacing + bottom_extent) * relativeY | |
| 107 up = guide | |
| 108 anchorFrom = vertFrom .. horizFrom | |
| 109 anchorTo = vertFrom .. horizFrom | |
| 110 bottom_extent = 0 | |
| 111 else | |
| 112 parent = g[i-1] | |
| 113 x = buffSpacing * relativeX | |
| 114 anchorFrom = vertFrom .. horizFrom | |
| 115 anchorTo = vertFrom .. horizTo | |
| 116 end | |
| 117 previous = guide | |
| 118 guide.parent = parent | |
| 119 | |
| 120 --------------------------------- | |
| 121 -- Positioning layer | |
| 122 if i ~= consolidatedPosition or not consolidated then | |
| 123 guide:SetSize(buffSize, buffSize + buffDurationSize) | |
| 124 -- RaidBuffTray will fix the sizing | |
| 125 end | |
| 126 bottom_extent = max(bottom_extent, guide:GetHeight()) | |
| 127 | |
| 128 guide.info = {} -- UnitAura cache | |
| 129 | |
| 130 if i == consolidatedPosition then | |
| 131 guide.legend:SetTexture(1,1,0,0.5) | |
| 132 else | |
| 133 guide.legend:SetTexture(legend.r, legend.g, legend.b, legend.a) | |
| 134 end | |
| 135 | |
| 136 guide.idText:SetText(i) -- needs to reflect the current position | |
| 137 | |
| 138 guide:ClearAllPoints() | |
| 139 guide:SetPoint(anchorFrom, parent, anchorTo, x, y) | |
| 140 print(anchorFrom, parent, anchorTo, x, y) | |
| 141 | |
| 142 guide.icon:SetSize(buffSize - buffBorder * 2, buffSize - buffBorder * 2) | |
| 143 guide.icon:ClearAllPoints() | |
| 144 guide.icon:SetPoint('TOPLEFT', guide, 'TOPLEFT', buffBorder, -buffBorder ) | |
| 145 | |
| 146 local anchorTo, anchorFrom, x, y = unpack(c.DurationPoint) | |
| 147 guide.duration:ClearAllPoints() | |
| 148 guide.duration:SetPoint(anchorTo, guide, anchorFrom, x, y) | |
| 149 --guide.duration:SetSize(buffSize, buffDurationSize) | |
| 150 print(' duration ->', anchorFrom, anchorTo, x, y) | |
| 151 | |
| 152 local anchorTo, anchorFrom, x, y = unpack(c.CountPoint) | |
| 153 guide.count:ClearAllPoints() | |
| 154 guide.count:SetPoint(anchorTo, guide.icon, anchorFrom, x, y) | |
| 155 --guide.count:SetSize(buffSize, c.CountSize) | |
| 156 print(' count ->', anchorFrom, anchorTo, x, y) | |
| 157 | |
| 158 ----------------------------------- | |
| 159 -- Background decorations layer | |
| 160 if not d[i] then | |
| 161 d[i] = CreateFrame('Frame', buffName..i..'Decor', _G.UIParent, 'VeneerDecorTemplate') | |
| 162 RegisterStateDriver(d[i], "visibility", "[petbattle] [vehicleui] hide") | |
| 163 end | |
| 164 | |
| 165 d[i]:SetPoint('BOTTOMLEFT', guide.icon, 'BOTTOMLEFT', -buffBorder, -buffBorder) | |
| 166 d[i]:SetPoint('TOPRIGHT', guide.icon, 'TOPRIGHT', buffBorder, buffBorder) | |
| 167 | |
| 168 | |
| 169 guide:Show() | |
| 170 B.SetConfigLayers(guide) | |
| 171 end | |
| 172 | |
| 173 | |
| 174 if #guides[buffName] > buffMax then | |
| 175 local lim = #guides[buffName] | |
| 176 for i = buffMax+1, lim do | |
| 177 | |
| 178 local g = guides[buffName][i] | |
| 179 if g:IsVisible() then | |
| 180 print('cleaning up #', i, buffName) | |
| 181 g:Hide() | |
| 182 B.RemoveConfigLayers(g) | |
| 183 end | |
| 184 | |
| 185 end | |
| 186 end | |
| 187 | |
| 188 anchor.last = previous | |
| 189 anchor.up = up | |
| 190 | |
| 191 print(anchor:GetName(), anchor:GetSize()) | |
| 192 end | |
| 193 | |
| 194 M.UpdateButtonPositions = function(buffName, auraType) | |
| 195 local print = fprint() | |
| 196 local c = auraType.conf | |
| 197 local numBuffs = 0 | |
| 198 local actualIcons = auraType.actualIcons() | |
| 199 local maxIcons = auraType.maxIcons | |
| 200 local anchor = anchors[buffName] | |
| 201 local buffMax = c['Max'] | |
| 202 local consolidated = (anchor.contains and IsInGroup()) | |
| 203 local consolidatedPosition = (consolidated and anchor.containPosition or 0) | |
| 204 | |
| 205 for k,v in pairs(decors[buffName]) do | |
| 206 print(v) | |
| 207 end | |
| 208 | |
| 209 if consolidated then | |
| 210 decors[buffName][1]:Hide() | |
| 211 numBuffs = numBuffs + 1 | |
| 212 buffMax = buffMax + 1 | |
| 213 end | |
| 214 | |
| 215 print(' ', 'frame count:', auraType.actualIcons(), 'hardmax:', maxIcons) | |
| 216 if auraType.actualIcons() > 0 then | |
| 217 for i = 1, actualIcons do | |
| 218 | |
| 219 | |
| 220 local buff = _G[buffName .. i] | |
| 221 local buffIcon = _G[buffName .. i .. 'Icon'] | |
| 222 local buffBorder = c['Border'] | |
| 223 local buffDuration = _G[buffName .. i .. 'Duration'] | |
| 224 local buffCount = _G[buffName .. i .. 'Count'] | |
| 225 local buffDurationSize = c['DurationSize'] | |
| 226 local debuffBorder = _G[buffName .. i .. 'Border'] | |
| 227 | |
| 228 | |
| 229 if buff and not buff.consolidated then | |
| 230 numBuffs = numBuffs + 1 | |
| 231 local guide = guides[buffName][numBuffs] | |
| 232 local deco = decors[buffName][numBuffs] | |
| 233 if numBuffs > buffMax then | |
| 234 -- if a limit is reached, start hiding | |
| 235 if guide then | |
| 236 guide.info = nil | |
| 237 end | |
| 238 if deco then | |
| 239 deco:Hide() | |
| 240 end | |
| 241 buff:Hide() | |
| 242 else | |
| 243 local buffData = guide.info | |
| 244 buffData.name, buffData.rank, buffData.icon, buffData.count, buffData.dispelType, buffData.duration, buffData.expires, buffData.caster, buffData.isStealable, buffData.shouldConsolidate, buffData.spellID, buffData.canApplyAura, buffData.isBossDebuff, buffData.value1, buffData.value2, buffData.value3 | |
| 245 = UnitAura(buff.unit, buff:GetID(), nil, buff.filters) | |
| 246 | |
| 247 if guide.caster and buffData.caster then | |
| 248 if (buffData.caster ~= 'player' or c.ShowSelfCast) then | |
| 249 guide.caster:SetText(UnitName(buffData.caster)) | |
| 250 else | |
| 251 guide.caster:SetText(nil) | |
| 252 end | |
| 253 end | |
| 254 | |
| 255 | |
| 256 print(numBuffs, i, buff:GetName(), buff:GetID(), decors[buffName][numBuffs]:GetName()) | |
| 257 | |
| 258 buff:SetAllPoints(guide) | |
| 259 buffIcon:ClearAllPoints() | |
| 260 buffIcon:SetPoint('TOPLEFT', guide.icon, 'TOPLEFT', 0, 0) | |
| 261 buffIcon:SetPoint('BOTTOMRIGHT', guide.icon, 'BOTTOMRIGHT', 0, 0) | |
| 262 | |
| 263 deco.parent = buff | |
| 264 -- make sure so they aren't re-shown in pet battle | |
| 265 if not C_PetBattles.IsInBattle() then | |
| 266 deco:Show() | |
| 267 deco:SetAlpha(1) | |
| 268 end | |
| 269 | |
| 270 if debuffBorder then | |
| 271 deco.background:SetTexture(debuffBorder:GetVertexColor()) | |
| 272 debuffBorder:Hide() | |
| 273 else | |
| 274 if guide.info.caster == 'player' then | |
| 275 print(guide.info.caster) | |
| 276 deco.background:SetTexture(unpack(c.PlayerColor)) | |
| 277 elseif buffData.isBossDebuff then | |
| 278 print(guide.info.isBossDebuff) | |
| 279 deco.background:SetTexture(unpack(c.BossColor)) | |
| 280 else | |
| 281 print(guide.info.caster) | |
| 282 deco.background:SetTexture(unpack(c.Color)) | |
| 283 end | |
| 284 end | |
| 285 | |
| 286 | |
| 287 buffDuration:ClearAllPoints() | |
| 288 local from, to = unpack(c.DurationPoint) | |
| 289 buffDuration:SetPoint(from, guide.duration, to) | |
| 290 buffDuration:SetText('WHAT') | |
| 291 | |
| 292 if buff.timeLeft and c.WarningFade then | |
| 293 deco:SetScript('OnUpdate', M.UpdateButtonAlpha) | |
| 294 else | |
| 295 deco:SetScript('OnUpdate', nil) | |
| 296 deco:SetAlpha(1.0) | |
| 297 end | |
| 298 | |
| 299 buffCount:ClearAllPoints() | |
| 300 local from, to = unpack(c.CountPoint) | |
| 301 buffCount:SetPoint(from, guide.count, to) | |
| 302 | |
| 303 if not drawn[buffName][numBuffs] then | |
| 304 anchors[buffName].Zoom(buffIcon) | |
| 305 | |
| 306 if buffDuration then | |
| 307 local font = buffDuration:GetFont() | |
| 308 buffDuration:SetFont(font, c.DurationSize, 'OUTLINE') | |
| 309 | |
| 310 end | |
| 311 | |
| 312 if buffCount then | |
| 313 local font = buffCount:GetFont() | |
| 314 buffCount:SetFont(font, c.CountSize, 'OUTLINE') | |
| 315 end | |
| 316 drawn[buffName][numBuffs] = true | |
| 317 end | |
| 318 end | |
| 319 end | |
| 320 | |
| 321 end | |
| 322 end | |
| 323 -- clear any outliers | |
| 324 for i = numBuffs+1, buffMax do | |
| 325 if guides[buffName][i].caster then | |
| 326 guides[buffName][i].caster:SetText(nil) | |
| 327 end | |
| 328 --if not decors[buffName][i].parent or | |
| 329 | |
| 330 decors[buffName][i].parent = nil | |
| 331 decors[buffName][i]:SetAlpha(1.0) | |
| 332 decors[buffName][i]:SetScript('OnUpdate', nil) | |
| 333 decors[buffName][i]:Hide() | |
| 334 end | |
| 335 | |
| 336 -- parametric occlusion data for compacted anchor points | |
| 337 if numBuffs == 0 then | |
| 338 anchor.cutout_X = 0 | |
| 339 anchor.cutout_Y = 0 | |
| 340 anchor.outer_X = 0 | |
| 341 anchor.outer_Y = 0 | |
| 342 elseif numBuffs <= buffMax then | |
| 343 local sX, sY = guides[buffName][numBuffs]:GetWidth(), guides[buffName][numBuffs]:GetHeight() | |
| 344 local p = c.PerRow | |
| 345 local lX = mod(numBuffs, p) | |
| 346 local lY = floor(numBuffs / p) | |
| 347 local oX = min(numBuffs, c.PerRow) | |
| 348 local oY = ceil(numBuffs / p) | |
| 349 anchor.cutout_X = lX * sX + lX * c.Spacing -- max clearance to fit alongside the row | |
| 350 anchor.cutout_Y = lY * sY + lY * c.Spacing | |
| 351 anchor.outer_Y = oY * sY + oY * c.Spacing -- distance of farthest row | |
| 352 anchor.outer_X = oX * sX + oX * c.Spacing | |
| 353 | |
| 354 | |
| 355 print('|cFF0088FF', 'inner corner', lX, lY, 'outer corners', oX, oY) | |
| 356 print('cutout delta =', anchor.cutout_X, anchor.cutout_Y, 'out of', floor(anchor:GetWidth()), floor(anchor:GetHeight())) | |
| 357 print('extent delta =', anchor.outer_X, anchor.outer_Y) | |
| 358 else | |
| 359 anchor.cutout_X = 0 | |
| 360 anchor.cutout_Y = 0 | |
| 361 anchor.outer_X = 0 | |
| 362 anchor.outer_Y = 0 | |
| 363 end | |
| 364 | |
| 365 if anchor.attached then | |
| 366 M.UpdateAnchorChild(anchor, anchor.attached, anchor.attachmentConf) | |
| 367 end | |
| 368 | |
| 369 end | |
| 370 | |
| 371 M.PostBuffAnchors = function() | |
| 372 local print = fprint() | |
| 373 if M.ShowConsolidatedBuffs then | |
| 374 M.UpdateRaidBuffs() | |
| 375 end | |
| 376 for buttonName, auraType in pairs(displays) do | |
| 377 print('sending', buttonName, auraType) | |
| 378 -- if waiting for anchors | |
| 379 if not anchors[buttonName] then | |
| 380 return | |
| 381 end | |
| 382 | |
| 383 --if positioned[buttonName] == 0 then | |
| 384 print('possibly reloaded UI, check positions') | |
| 385 M.UpdateGuideFrames(buttonName) | |
| 386 --end | |
| 387 | |
| 388 M.UpdateButtonPositions(buttonName, auraType) | |
| 389 end | |
| 390 end | |
| 391 | |
| 392 M.UpdateBuffs = function(buttonName, forced) | |
| 393 local print = B.fprint(buttonName) | |
| 394 local c = displays[buttonName].conf | |
| 395 if drawn[buttonName] then | |
| 396 wipe(drawn[buttonName]) | |
| 397 else | |
| 398 drawn[buttonName] = {} | |
| 399 end | |
| 400 | |
| 401 M.UpdateAnchorFrames(buttonName) | |
| 402 M.UpdateGuideFrames(buttonName) | |
| 403 M.UpdateButtonPositions(buttonName, displays[buttonName]) | |
| 404 end | |
| 405 | |
| 406 --- should only be called from user input | |
| 407 print('init def') | |
| 408 function M:OnInitialize () | |
| 409 drawn = B.Abstract(B.displays, 'drawn') | |
| 410 -- Lesser extent of guide frames that have been positioned | |
| 411 positioned = B.Abstract(B.displays, 'positioned', positioned) | |
| 412 -- Backdrop style frame | |
| 413 decors = B.Abstract(B.displays, 'decorator', decors) | |
| 414 -- Static positioning frames | |
| 415 guides = B.Abstract(B.displays, 'guides', guides) | |
| 416 -- Anchor points for guides | |
| 417 anchors = B.Abstract(B.displays, 'anchor') | |
| 418 -- Stored functions for doing icon texture adjustments | |
| 419 zoom = B.Abstract(B.displays, 'zoom', zoom) | |
| 420 | |
| 421 B:RegisterUnitEvent("UNIT_AURA", "player", "vehicle") | |
| 422 B:RegisterEvent("GROUP_ROSTER_UPDATE") | |
| 423 B:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED") | |
| 424 hooksecurefunc("BuffFrame_UpdateAllBuffAnchors", M.PostBuffAnchors) | |
| 425 hooksecurefunc("RaidBuffTray_Update", M.UpdateRaidBuffs) | |
| 426 end | |
| 427 print('update def') | |
| 428 function M:OnUpdate () | |
| 429 M.ShowConsolidated = (IsInGroup() and GetCVarBool("consolidateBuffs")) | |
| 430 M.ShowMissingBuffs = (IsInGroup() and B.Conf.RaidShowMissing) | |
| 431 | |
| 432 for name, auraType in pairs(displays) do | |
| 433 print(name, auraType) | |
| 434 M.UpdateBuffs(auraType.buffName, true) | |
| 435 end | |
| 436 | |
| 437 M.UpdateAnchorAnchors() | |
| 438 M.UpdateRaidBuffs() | |
| 439 M.UpdateBuffsTodo() | |
| 440 end |
