File src/ChorusAuraButtonTemplate.lua changed (mode: 100644) (index 0fb5a03..261627e) |
... |
... |
local function applyOverlay(auraButton, category, owner) |
117 |
117 |
|
|
118 |
118 |
overlay:SetVertexColor(r, g, b) |
overlay:SetVertexColor(r, g, b) |
119 |
119 |
|
|
120 |
|
--[[ ShadowedUnitFrames recommend this approach for adjusting font size. ]]-- |
|
121 |
120 |
local label = auraButton.label |
local label = auraButton.label |
122 |
121 |
assert(label ~= nil) |
assert(label ~= nil) |
123 |
|
local t = label:GetText() |
|
124 |
|
if t ~= nil and string.len(t) >= 1 then |
|
125 |
|
local fontSize = 12 |
|
126 |
|
auraButton:SetScale(label:GetStringHeight() / fontSize) |
|
127 |
|
end |
|
128 |
|
|
|
129 |
122 |
if owner and 'player' == owner then |
if owner and 'player' == owner then |
130 |
123 |
label:SetTextColor(1, 225 / 255, 0) |
label:SetTextColor(1, 225 / 255, 0) |
131 |
124 |
else |
else |
132 |
125 |
label:SetTextColor(1, 1, 1) |
label:SetTextColor(1, 1, 1) |
133 |
126 |
end |
end |
|
127 |
|
overlay:SetAlpha(1) |
134 |
128 |
end |
end |
135 |
129 |
|
|
136 |
130 |
--[[-- |
--[[-- |
|
... |
... |
processor function. |
277 |
271 |
@return nothing |
@return nothing |
278 |
272 |
]] |
]] |
279 |
273 |
local function auraButtonUpdateProcessor(self) |
local function auraButtonUpdateProcessor(self) |
280 |
|
local unitDesignation = SecureButton_GetUnit(self) |
|
|
274 |
|
--[[-- @warning This function is executed every frame for every unit |
|
275 |
|
aura button. It must be optimized as much as possible.]] |
|
276 |
|
|
|
277 |
|
--[[-- It is not throttled for the sake of accuracy. Maybe it should |
|
278 |
|
be. ]] |
|
279 |
|
|
281 |
280 |
local index = self.index |
local index = self.index |
|
281 |
|
if not index then |
|
282 |
|
return |
|
283 |
|
end |
|
284 |
|
|
|
285 |
|
local unitDesignation = SecureButton_GetUnit(self) |
|
286 |
|
if not unitDesignation then |
|
287 |
|
return |
|
288 |
|
end |
|
289 |
|
|
282 |
290 |
local filter = SecureButton_GetAttribute(self, 'filter') |
local filter = SecureButton_GetAttribute(self, 'filter') |
283 |
|
if not unitDesignation or not index then |
|
|
291 |
|
if not filter then |
284 |
292 |
return |
return |
285 |
293 |
end |
end |
|
294 |
|
|
286 |
295 |
local name, _, _, chargeQuantity, _, durationSec, expirationInstance = UnitAura(unitDesignation, index, filter) |
local name, _, _, chargeQuantity, _, durationSec, expirationInstance = UnitAura(unitDesignation, index, filter) |
287 |
296 |
if not name then |
if not name then |
288 |
297 |
return |
return |
|
... |
... |
local function auraButtonUpdateProcessor(self) |
291 |
300 |
applyChargeQuantity(self, chargeQuantity) |
applyChargeQuantity(self, chargeQuantity) |
292 |
301 |
end |
end |
293 |
302 |
|
|
|
303 |
|
--[[-- |
|
304 |
|
Obscure the aura button to the user's eye, without toggling frame visibility |
|
305 |
|
mechanically. |
|
306 |
|
|
|
307 |
|
Toggling visibility of a frame is a restricted action. That is, it can only be |
|
308 |
|
done in combat by trusted or secure frames. The aura buttons, for the sake of |
|
309 |
|
their core features, are not secure or trusted frames. Therefore, they must |
|
310 |
|
never be toggled with `Show` or `Hide` frame methods. |
|
311 |
|
|
|
312 |
|
This implementation must also leave to traces in the taint log. |
|
313 |
|
(Logs/taint.log) |
|
314 |
|
|
|
315 |
|
@see InCombatLockdown |
|
316 |
|
@see issecure |
|
317 |
|
|
|
318 |
|
@function unapply |
|
319 |
|
@tparam frame auraButton this aura button |
|
320 |
|
@return nothing, only side effects |
|
321 |
|
]] |
|
322 |
|
local function unapply(auraButton) |
|
323 |
|
assert(auraButton ~= nil) |
|
324 |
|
|
|
325 |
|
auraButton.index = nil |
|
326 |
|
auraButton.spell = nil |
|
327 |
|
|
|
328 |
|
local artwork = auraButton.artwork |
|
329 |
|
assert(artwork ~= nil) |
|
330 |
|
artwork:SetTexture(artworkFile) |
|
331 |
|
artwork:SetAlpha(1) |
|
332 |
|
|
|
333 |
|
--[[ Remaining duration ]]-- |
|
334 |
|
local label = auraButton.label |
|
335 |
|
assert (label ~= nil) |
|
336 |
|
label:SetText(nil) |
|
337 |
|
|
|
338 |
|
--[[ Remaining charge quantity ]]-- |
|
339 |
|
local label2 = auraButton.label2 |
|
340 |
|
assert (label2 ~= nil) |
|
341 |
|
label2:SetText(nil) |
|
342 |
|
|
|
343 |
|
local overlay = auraButton.overlay |
|
344 |
|
assert(overlay ~= nil) |
|
345 |
|
overlay:SetAlpha(0) |
|
346 |
|
end |
|
347 |
|
|
294 |
348 |
--[[-- |
--[[-- |
295 |
349 |
Request relevant aura details, then apply them to the aura button. |
Request relevant aura details, then apply them to the aura button. |
296 |
350 |
|
|
|
... |
... |
local function apply(auraButton, unitDesignation, auraIndex, filter) |
328 |
382 |
assert(string.len(filter) >= 1) |
assert(string.len(filter) >= 1) |
329 |
383 |
assert(string.len(filter) <= 256) |
assert(string.len(filter) <= 256) |
330 |
384 |
|
|
331 |
|
--[[ @warning Aura button event processor might fail in restricted |
|
332 |
|
environment. ]]-- |
|
333 |
|
|
|
334 |
385 |
if not UnitExists(unitDesignation) or not UnitIsConnected(unitDesignation) then |
if not UnitExists(unitDesignation) or not UnitIsConnected(unitDesignation) then |
335 |
|
auraButton:Hide() |
|
336 |
|
auraButton:SetScript('OnUpdate', nil) |
|
|
386 |
|
unapply(auraButton) |
337 |
387 |
return |
return |
338 |
388 |
end |
end |
339 |
389 |
|
|
340 |
390 |
local name, _, artworkFile, chargeQuantity, category, durationSec, expirationInstance, |
local name, _, artworkFile, chargeQuantity, category, durationSec, expirationInstance, |
341 |
391 |
owner = UnitAura(unitDesignation, auraIndex, filter) |
owner = UnitAura(unitDesignation, auraIndex, filter) |
342 |
|
if name then |
|
343 |
|
auraButton:Show() |
|
344 |
|
auraButton:SetScript('OnUpdate', auraButtonUpdateProcessor) |
|
345 |
|
else |
|
346 |
|
auraButton:Hide() |
|
347 |
|
auraButton:SetScript('OnUpdate', nil) |
|
|
392 |
|
if not name then |
|
393 |
|
unapply(auraButton) |
348 |
394 |
return |
return |
349 |
395 |
end |
end |
350 |
396 |
|
|
|
... |
... |
watch that unit, then apply relevant changes to the aura button. |
371 |
417 |
function Chorus.auraButtonEventProcessor(self, eventCategory, ...) |
function Chorus.auraButtonEventProcessor(self, eventCategory, ...) |
372 |
418 |
auraButtonValidate(self) |
auraButtonValidate(self) |
373 |
419 |
|
|
374 |
|
local u = SecureButton_GetUnit(self) or 'none' |
|
375 |
|
assert(u ~= nil) |
|
376 |
|
assert('string' == type(u)) |
|
377 |
|
u = string.lower(strtrim(u)) |
|
378 |
|
assert(string.len(u) >= 1) |
|
379 |
|
assert(string.len(u) <= 256) |
|
|
420 |
|
local thisUnit = SecureButton_GetUnit(self) or 'none' |
|
421 |
|
assert(thisUnit ~= nil) |
|
422 |
|
assert('string' == type(thisUnit)) |
|
423 |
|
thisUnit = string.lower(strtrim(thisUnit)) |
|
424 |
|
assert(string.len(thisUnit) >= 1) |
|
425 |
|
assert(string.len(thisUnit) <= 256) |
|
426 |
|
|
|
427 |
|
assert(eventCategory ~= nil) |
|
428 |
|
assert('string' == type(eventCategory)) |
|
429 |
|
eventCategory = string.upper(strtrim(eventCategory)) |
|
430 |
|
assert(string.len(eventCategory) >= 1) |
|
431 |
|
assert(string.len(eventCategory) <= 256) |
380 |
432 |
|
|
381 |
|
--[[ Break if unit doesn't exist. ]]-- |
|
382 |
|
if UnitExists(u) and UnitIsConnected(u) then |
|
383 |
|
self:Show() |
|
384 |
|
else |
|
385 |
|
self:Hide() |
|
386 |
|
return |
|
387 |
|
end |
|
388 |
433 |
|
|
389 |
|
--[[ Break if event is not relevant to this button. ]]-- |
|
390 |
|
if eventCategory then |
|
391 |
|
assert(eventCategory ~= nil) |
|
392 |
|
assert('string' == type(eventCategory)) |
|
393 |
|
eventCategory = string.upper(strtrim(eventCategory)) |
|
394 |
|
assert(string.len(eventCategory) >= 1) |
|
395 |
|
assert(string.len(eventCategory) <= 256) |
|
396 |
|
|
|
397 |
|
local o = select(1, ...) |
|
398 |
|
if eventCategory == 'UNIT_AURA' and o and not UnitIsUnit(u, o) then |
|
399 |
|
self:Hide() |
|
|
434 |
|
if 'ADDON_LOADED' == tostring(eventCategory) then |
|
435 |
|
--[[-- @warning Hardcoded addon name here. |
|
436 |
|
]] |
|
437 |
|
|
|
438 |
|
local loadedAddonName = select(1, ...) |
|
439 |
|
local thisAddonName = 'chorus' |
|
440 |
|
if thisAddonName ~= tostring(loadedAddonName) then |
|
441 |
|
return |
|
442 |
|
end |
|
443 |
|
elseif 'UNIT_AURA' == tostring(eventCategory) then |
|
444 |
|
local otherUnit = select(1, ...) |
|
445 |
|
if not UnitIsUnit(thisUnit, otherUnit) then |
400 |
446 |
return |
return |
401 |
447 |
end |
end |
402 |
448 |
end |
end |
403 |
449 |
|
|
|
450 |
|
if not UnitExists(thisUnit) or not UnitIsConnected(thisUnit) then |
|
451 |
|
unapply(self) |
|
452 |
|
return |
|
453 |
|
end |
|
454 |
|
|
404 |
455 |
--[[ Do work. ]]-- |
--[[ Do work. ]]-- |
405 |
456 |
local i = self.index or 0 |
local i = self.index or 0 |
406 |
457 |
assert(i ~= nil) |
assert(i ~= nil) |
|
... |
... |
function Chorus.auraButtonEventProcessor(self, eventCategory, ...) |
414 |
465 |
assert(string.len(filter) >= 1) |
assert(string.len(filter) >= 1) |
415 |
466 |
assert(string.len(filter) <= 256) |
assert(string.len(filter) <= 256) |
416 |
467 |
|
|
417 |
|
apply(self, u, i, filter) |
|
|
468 |
|
apply(self, thisUnit, i, filter) |
418 |
469 |
end |
end |
419 |
470 |
|
|
420 |
471 |
--[[-- |
--[[-- |
|
... |
... |
function Chorus.auraButtonGameTooltipHide() |
455 |
506 |
GameTooltip:Hide(); |
GameTooltip:Hide(); |
456 |
507 |
end |
end |
457 |
508 |
|
|
|
509 |
|
local function auraButtonTextScale(auraButton) |
|
510 |
|
assert(auraButton ~= nil) |
|
511 |
|
|
|
512 |
|
--[[ ShadowedUnitFrames recommend this approach for adjusting font |
|
513 |
|
size. ]]-- |
|
514 |
|
|
|
515 |
|
--[[ Only do this at initialization to save on processing and prevent |
|
516 |
|
visual flicker. ]]-- |
|
517 |
|
|
|
518 |
|
local label = auraButton.label |
|
519 |
|
assert(label ~= nil) |
|
520 |
|
local t = label:GetText() |
|
521 |
|
if t ~= nil and string.len(t) >= 1 then |
|
522 |
|
local fontSize = 12 |
|
523 |
|
auraButton:SetScale(label:GetStringHeight() / fontSize) |
|
524 |
|
end |
|
525 |
|
end |
|
526 |
|
|
458 |
527 |
--[[-- |
--[[-- |
459 |
528 |
Initialize the aura button frame with callbacks and children. |
Initialize the aura button frame with callbacks and children. |
460 |
529 |
|
|
|
... |
... |
function Chorus.auraButtonMain(self) |
471 |
540 |
self.overlay = _G[n .. 'Overlay'] |
self.overlay = _G[n .. 'Overlay'] |
472 |
541 |
end |
end |
473 |
542 |
self:SetScript('OnEvent', Chorus.auraButtonEventProcessor) |
self:SetScript('OnEvent', Chorus.auraButtonEventProcessor) |
|
543 |
|
self:SetScript('OnUpdate', auraButtonUpdateProcessor) |
474 |
544 |
self:RegisterEvent('ADDON_LOADED') |
self:RegisterEvent('ADDON_LOADED') |
475 |
545 |
self:RegisterEvent('UNIT_AURA') |
self:RegisterEvent('UNIT_AURA') |
476 |
546 |
auraButtonValidate(self) |
auraButtonValidate(self) |
|
547 |
|
|
|
548 |
|
auraButtonTextScale(self) |
477 |
549 |
end |
end |
File src/ChorusAuraFrameTemplate.lua changed (mode: 100644) (index 11fd547..25ea6da) |
... |
... |
end |
85 |
85 |
local function auraFrameEventProcessor(self, eventCategory, ...) |
local function auraFrameEventProcessor(self, eventCategory, ...) |
86 |
86 |
assert(self ~= nil) |
assert(self ~= nil) |
87 |
87 |
|
|
88 |
|
--[[ Optimization hack ]]-- |
|
89 |
|
--[[ Make it use table value if it lags again. ]]-- |
|
90 |
88 |
local unitDesignation = SecureButton_GetUnit(self) or 'none' |
local unitDesignation = SecureButton_GetUnit(self) or 'none' |
91 |
89 |
assert(unitDesignation ~= nil) |
assert(unitDesignation ~= nil) |
92 |
90 |
assert('string' == type(unitDesignation)) |
assert('string' == type(unitDesignation)) |
|
... |
... |
local function auraFrameEventProcessor(self, eventCategory, ...) |
94 |
92 |
assert(string.len(unitDesignation) >= 1) |
assert(string.len(unitDesignation) >= 1) |
95 |
93 |
assert(string.len(unitDesignation) <= 256) |
assert(string.len(unitDesignation) <= 256) |
96 |
94 |
|
|
97 |
|
if UnitExists(unitDesignation) and UnitIsConnected(unitDesignation) then |
|
98 |
|
self:Show() |
|
99 |
|
else |
|
100 |
|
self:Hide() |
|
101 |
|
return |
|
102 |
|
end |
|
|
95 |
|
--[[-- @fixme Taint here. |
|
96 |
|
]] |
103 |
97 |
|
|
104 |
|
if 'UNIT_AURA' == eventCategory then |
|
|
98 |
|
if 'UNIT_AURA' == tostring(eventCategory) then |
105 |
99 |
local u = select(1, ...) |
local u = select(1, ...) |
106 |
|
if u and 'string' == type(u) and unitDesignation ~= u then |
|
|
100 |
|
if not UnitIsUnit(unitDesignation, u) then |
|
101 |
|
return |
|
102 |
|
end |
|
103 |
|
elseif 'PLAYER_FOCUS_CHANGED' == tostring(eventCategory) then |
|
104 |
|
if not UnitIsUnit(unitDesignation, 'focus') then |
|
105 |
|
return |
|
106 |
|
end |
|
107 |
|
elseif 'PLAYER_TARGET_CHANGED' == tostring(eventCategory) then |
|
108 |
|
if not UnitIsUnit(unitDesignation, 'target') then |
107 |
109 |
return |
return |
108 |
110 |
end |
end |
109 |
111 |
end |
end |
110 |
112 |
|
|
111 |
|
--[[ Make it use table value if it lags again. ]]-- |
|
|
113 |
|
assert(eventCategory ~= nil) |
|
114 |
|
|
112 |
115 |
local filter = SecureButton_GetAttribute(self, 'filter') |
local filter = SecureButton_GetAttribute(self, 'filter') |
113 |
116 |
assert(filter ~= nil) |
assert(filter ~= nil) |
114 |
117 |
assert('string' == type(filter)) |
assert('string' == type(filter)) |
|
... |
... |
function Chorus.auraFrameMain(self) |
239 |
242 |
self.filter = SecureButton_GetAttribute(self, 'filter') |
self.filter = SecureButton_GetAttribute(self, 'filter') |
240 |
243 |
|
|
241 |
244 |
self:SetScript('OnEvent', auraFrameEventProcessor) |
self:SetScript('OnEvent', auraFrameEventProcessor) |
242 |
|
self:SetScript('OnShow', auraFrameEventProcessor) |
|
|
245 |
|
--self:SetScript('OnShow', auraFrameEventProcessor) |
243 |
246 |
|
|
244 |
247 |
if auraWeightMap then |
if auraWeightMap then |
245 |
248 |
validateAuraWeightMap(auraWeightMap) |
validateAuraWeightMap(auraWeightMap) |