File choir.lua changed (mode: 100644) (index 50eb78a..82576d2) |
... |
... |
local function createClearcastingSubset(unitButton) |
24 |
24 |
|
|
25 |
25 |
local harmSubset = createSubset(unitButton, unitButton:GetName() .. 'HarmfulSubsetFrame', |
local harmSubset = createSubset(unitButton, unitButton:GetName() .. 'HarmfulSubsetFrame', |
26 |
26 |
unitDesignation, 'HARMFUL', |
unitDesignation, 'HARMFUL', |
27 |
|
5, 1) |
|
|
27 |
|
8, 1) |
28 |
28 |
harmSubset:SetPoint('BOTTOMLEFT', 0, 0) |
harmSubset:SetPoint('BOTTOMLEFT', 0, 0) |
29 |
29 |
|
|
30 |
|
--[[ TODO Track tank defensives in addition to player (healer) buffs. ]]-- |
|
31 |
30 |
local helpSubset = createSubset(unitButton, unitButton:GetName() .. 'HelpfulSubsetFrame', |
local helpSubset = createSubset(unitButton, unitButton:GetName() .. 'HelpfulSubsetFrame', |
32 |
31 |
unitDesignation, 'HELPFUL', |
unitDesignation, 'HELPFUL', |
33 |
|
5, 1) |
|
|
32 |
|
8, 1) |
34 |
33 |
helpSubset:SetPoint('BOTTOMLEFT', 0, harmSubset:GetHeight()) |
helpSubset:SetPoint('BOTTOMLEFT', 0, harmSubset:GetHeight()) |
35 |
34 |
|
|
36 |
35 |
return harmSubset, helpSubset |
return harmSubset, helpSubset |
|
... |
... |
local function createBackground(ownerFrame) |
142 |
141 |
return background |
return background |
143 |
142 |
end |
end |
144 |
143 |
|
|
|
144 |
|
local function getRoleTexCoord(isTank, isHealer, isDamager) |
|
145 |
|
local size = 64 |
|
146 |
|
if isTank then |
|
147 |
|
return 0 / size, 19 / size, 22 / size, 41 / size |
|
148 |
|
elseif isHealer then |
|
149 |
|
return 20 / size, 39 / size, 1 / size, 20 / size |
|
150 |
|
elseif isDamager then |
|
151 |
|
return 20 / size, 39 / size, 22 / size, 41 / size |
|
152 |
|
else |
|
153 |
|
error('invalid argument') |
|
154 |
|
end |
|
155 |
|
end |
|
156 |
|
|
|
157 |
|
local function updateUnitButtonRoleWidget(roleWidget, unitDesignation) |
|
158 |
|
assert (roleWidget ~= nil) |
|
159 |
|
assert (unitDesignation ~= nil) |
|
160 |
|
|
|
161 |
|
local isTank, isHealer, isDamager = UnitGroupRolesAssigned(unitDesignation) |
|
162 |
|
|
|
163 |
|
--[[ Corner-case for Interface >= 40000 ]]-- |
|
164 |
|
if 'string' == type(isTank) then |
|
165 |
|
local roleDesignation = isTank |
|
166 |
|
isTank = 'TANK' == roleDesignation |
|
167 |
|
isHealer = 'HEALER' == roleDesignation |
|
168 |
|
isDamager = 'DAMAGER' == roleDesignation |
|
169 |
|
end |
|
170 |
|
|
|
171 |
|
if isTank or isHealer or isDamager then |
|
172 |
|
roleWidget:Show() |
|
173 |
|
roleWidget:SetTexCoord(getRoleTexCoord(isTank, isHealer, isDamager)) |
|
174 |
|
else |
|
175 |
|
roleWidget:Hide() |
|
176 |
|
end |
|
177 |
|
end |
|
178 |
|
|
145 |
179 |
local function createUnitButtonRoleWidget(unitButton) |
local function createUnitButtonRoleWidget(unitButton) |
146 |
180 |
assert (unitButton ~= nil) |
assert (unitButton ~= nil) |
147 |
181 |
|
|
148 |
|
local widgetSize = 12 |
|
149 |
|
local roleWidget = unitButton:CreateTexture(unitButton:GetName() .. 'RoleWidget', 'OVERLAY') |
|
150 |
|
roleWidget:SetPoint('TOPRIGHT', unitButton, 'TOPRIGHT', 0, 0) |
|
151 |
|
roleWidget:SetPoint('BOTTOMLEFT', unitButton, 'TOPRIGHT', -widgetSize, -widgetSize) |
|
152 |
|
roleWidget:SetTexture("Interface\\LFGFrame\\UI-LFG-ICON-PORTRAITROLES.blp") |
|
|
182 |
|
local n = unitButton:GetName() .. 'RoleWidgetFrame' |
|
183 |
|
|
|
184 |
|
local widgetSize = 16 |
|
185 |
|
local widgetFrame = CreateFrame('FRAME', n, unitButton) |
|
186 |
|
widgetFrame:SetPoint('TOPLEFT', 0, 0) |
|
187 |
|
widgetFrame:SetPoint('TOPRIGHT', 0, 0) |
|
188 |
|
widgetFrame:SetSize(unitButton:GetWidth(), widgetSize) |
|
189 |
|
|
|
190 |
|
local artwork = widgetFrame:CreateTexture(widgetFrame:GetName() .. 'Artwork', 'ARTWORK') |
|
191 |
|
artwork:SetPoint('TOPRIGHT', widgetFrame, 'TOPRIGHT', 0, 0) |
|
192 |
|
artwork:SetPoint('BOTTOMLEFT', widgetFrame, 'TOPRIGHT', -widgetSize, -widgetSize) |
|
193 |
|
artwork:SetTexture("Interface\\LFGFrame\\UI-LFG-ICON-PORTRAITROLES.blp") |
|
194 |
|
|
|
195 |
|
widgetFrame:RegisterEvent('LFG_ROLE_UPDATE') |
|
196 |
|
widgetFrame:RegisterEvent('PLAYER_ENTERING_WORLD') |
153 |
197 |
|
|
154 |
|
return roleWidget |
|
|
198 |
|
widgetFrame:SetScript('OnEvent', function(self, ...) |
|
199 |
|
local u = self:GetParent() |
|
200 |
|
updateUnitButtonRoleWidget(self, u:GetAttribute('unit')) |
|
201 |
|
end) |
|
202 |
|
|
|
203 |
|
return widgetFrame |
155 |
204 |
end |
end |
156 |
205 |
|
|
157 |
206 |
local function getUnitHealthDeficit(unitDesignation) |
local function getUnitHealthDeficit(unitDesignation) |
|
... |
... |
local function updateUnitButtonText(self) |
208 |
257 |
local unitDesignation = self:GetAttribute('unit') |
local unitDesignation = self:GetAttribute('unit') |
209 |
258 |
assert (unitDesignation ~= nil) |
assert (unitDesignation ~= nil) |
210 |
259 |
|
|
211 |
|
local n = UnitName(unitDesignation) or unitDesignation |
|
|
260 |
|
local n |
|
261 |
|
local unitName = UnitName(unitDesignation) |
|
262 |
|
if not unitName or string.len(unitName) < 2 then |
|
263 |
|
n = unitDesignation |
|
264 |
|
else |
|
265 |
|
n = unitName |
|
266 |
|
end |
|
267 |
|
|
|
268 |
|
local m = math.floor(self:GetWidth() / 16) |
|
269 |
|
local sanitizedName = string.sub(n, 1, m) |
|
270 |
|
if string.len(sanitizedName) < string.len(unitName) then |
|
271 |
|
sanitizedName = sanitizedName .. '…' |
|
272 |
|
end |
212 |
273 |
|
|
213 |
274 |
local key = GetBindingKey('CLICK ' .. self:GetName() .. ':LeftButton') |
local key = GetBindingKey('CLICK ' .. self:GetName() .. ':LeftButton') |
214 |
275 |
if not key then |
if not key then |
215 |
276 |
key = self:GetAttribute('choirBindingKey') |
key = self:GetAttribute('choirBindingKey') |
216 |
277 |
end |
end |
|
278 |
|
|
|
279 |
|
local y |
217 |
280 |
if key then |
if key then |
218 |
|
n = n .. ' <' .. key .. '>' |
|
|
281 |
|
y = ' <' .. key .. '>' |
|
282 |
|
else |
|
283 |
|
y = '' |
219 |
284 |
end |
end |
220 |
285 |
|
|
221 |
|
local m = math.floor(self:GetWidth() / 8) |
|
|
286 |
|
sanitizedName = sanitizedName .. y |
|
287 |
|
label:SetText(sanitizedName) |
222 |
288 |
|
|
223 |
|
label:SetText(string.sub(n, 1, m)) |
|
224 |
289 |
|
|
225 |
|
local r = 1 |
|
226 |
|
local g = 1 |
|
227 |
|
local b = 1 |
|
228 |
|
local threatStatus = UnitThreatSituation(unitDesignation) |
|
229 |
|
if threatStatus then |
|
230 |
|
r, g, b = GetThreatStatusColor(threatStatus) |
|
231 |
|
end |
|
232 |
|
label:SetTextColor(r, g, b) |
|
233 |
290 |
end |
end |
234 |
291 |
|
|
235 |
292 |
local function getClassColor(classDesignation) |
local function getClassColor(classDesignation) |
|
... |
... |
local function createUnitButtonBar(unitButton) |
291 |
348 |
local n = unitButton:GetName() or '' |
local n = unitButton:GetName() or '' |
292 |
349 |
local padding = 4 |
local padding = 4 |
293 |
350 |
local marginTop = 24 |
local marginTop = 24 |
294 |
|
local barHeight = 12 |
|
|
351 |
|
local barHeight = 20 |
295 |
352 |
local bar = CreateFrame('FRAME', n .. 'Bar', unitButton) |
local bar = CreateFrame('FRAME', n .. 'Bar', unitButton) |
296 |
353 |
bar:SetPoint('BOTTOMLEFT', unitButton, 'TOPLEFT', padding, -padding - marginTop - barHeight) |
bar:SetPoint('BOTTOMLEFT', unitButton, 'TOPLEFT', padding, -padding - marginTop - barHeight) |
297 |
354 |
bar:SetPoint('TOPRIGHT', unitButton, 'TOPRIGHT', -padding, -padding - marginTop) |
bar:SetPoint('TOPRIGHT', unitButton, 'TOPRIGHT', -padding, -padding - marginTop) |
|
... |
... |
local function createUnitButtonBar(unitButton) |
299 |
356 |
local b = bar:CreateTexture(bar:GetName() .. 'Overlay', 'OVERLAY') |
local b = bar:CreateTexture(bar:GetName() .. 'Overlay', 'OVERLAY') |
300 |
357 |
b:SetAllPoints() |
b:SetAllPoints() |
301 |
358 |
--b:SetTexture("Interface\\TARGETINGFRAME\\BarFill2") |
--b:SetTexture("Interface\\TARGETINGFRAME\\BarFill2") |
302 |
|
b:SetTexture("Interface\\TARGETINGFRAME\\UI-StatusBar") |
|
|
359 |
|
--b:SetTexture("Interface\\TARGETINGFRAME\\UI-StatusBar") |
303 |
360 |
--b:SetTexture("Interface\\TARGETINGFRAME\\UI-TargetingFrame-BarFill") |
--b:SetTexture("Interface\\TARGETINGFRAME\\UI-TargetingFrame-BarFill") |
|
361 |
|
b:SetTexture("Interface\\AddOns\\choir\\share\\Minimalist.tga") |
304 |
362 |
b:SetVertexColor(getDefaultUnitButtonBarColor(), 1) |
b:SetVertexColor(getDefaultUnitButtonBarColor(), 1) |
305 |
363 |
bar.overlay = b |
bar.overlay = b |
306 |
364 |
|
|
307 |
|
local t = createLabel(bar) |
|
|
365 |
|
local t = createLabel(bar, UnifontRegular16) |
308 |
366 |
bar.text = t |
bar.text = t |
309 |
367 |
|
|
310 |
368 |
bar.unitButton = unitButton |
bar.unitButton = unitButton |
311 |
369 |
|
|
312 |
370 |
--[[ Update health indicator ]]-- |
--[[ Update health indicator ]]-- |
313 |
|
bar:SetScript('OnEvent', function(healthBarFrame) |
|
|
371 |
|
bar:SetScript('OnEvent', function(healthBarFrame, eventCategory, targetUnit) |
314 |
372 |
assert (healthBarFrame ~= nil) |
assert (healthBarFrame ~= nil) |
|
373 |
|
assert (eventCategory ~= nil) |
315 |
374 |
assert (unitButton ~= nil) |
assert (unitButton ~= nil) |
316 |
375 |
|
|
317 |
376 |
local u = unitButton:GetAttribute('unit') |
local u = unitButton:GetAttribute('unit') |
318 |
377 |
assert (u ~= nil) |
assert (u ~= nil) |
|
378 |
|
|
|
379 |
|
if targetUnit and targetUnit ~= u then |
|
380 |
|
return |
|
381 |
|
end |
|
382 |
|
|
319 |
383 |
updateUnitButtonBarOverlay(healthBarFrame, u) |
updateUnitButtonBarOverlay(healthBarFrame, u) |
320 |
384 |
updateUnitButtonBarText(healthBarFrame, u) |
updateUnitButtonBarText(healthBarFrame, u) |
321 |
385 |
end) |
end) |
322 |
|
bar:RegisterEvent('PLAYER_FOCUS_CHANGED') |
|
323 |
|
bar:RegisterEvent('PLAYER_TARGET_CHANGED') |
|
324 |
386 |
bar:RegisterEvent('UNIT_HEALTH') |
bar:RegisterEvent('UNIT_HEALTH') |
325 |
387 |
--[[ NOTE UNIT_SPELLCAST_* family of events are relied on to render range indicator correctly, |
--[[ NOTE UNIT_SPELLCAST_* family of events are relied on to render range indicator correctly, |
326 |
388 |
-- instead of the more expensive update hook. ]]-- |
-- instead of the more expensive update hook. ]]-- |
|
... |
... |
local function createUnitButtonBar(unitButton) |
332 |
394 |
return bar |
return bar |
333 |
395 |
end |
end |
334 |
396 |
|
|
335 |
|
local function getRoleTexCoord(isTank, isHealer, isDamager) |
|
336 |
|
local size = 64 |
|
337 |
|
if isTank then |
|
338 |
|
return 0 / size, 19 / size, 22 / size, 41 / size |
|
339 |
|
elseif isHealer then |
|
340 |
|
return 20 / size, 39 / size, 1 / size, 20 / size |
|
341 |
|
elseif isDamager then |
|
342 |
|
return 20 / size, 39 / size, 22 / size, 41 / size |
|
|
397 |
|
local function healthBarEventProcessor(healthBarFrame, eventCategory, targetUnitDesignation) |
|
398 |
|
assert (healthBarFrame ~= nil) |
|
399 |
|
assert (eventCategory == 'UNIT_HEALTH' or eventCategory == 'UNIT_COMBAT') |
|
400 |
|
|
|
401 |
|
local unitButton = healthBarFrame:GetParent() |
|
402 |
|
assert (unitButton ~= nil) |
|
403 |
|
|
|
404 |
|
local unitDesignation = unitButton:GetAttribute('unit') |
|
405 |
|
assert (unitDesignation ~= nil) |
|
406 |
|
assert ('string' == type(unitDesignation)) |
|
407 |
|
unitDesignation = strtrim(unitDesignation) |
|
408 |
|
assert (string.len(unitDesignation) >= 2) |
|
409 |
|
assert (string.len(unitDesignation) <= 32) |
|
410 |
|
|
|
411 |
|
--[[ Assume UNIT_HEALTH event is processed for the relevant unit. ]]-- |
|
412 |
|
if targetUnitDesignation ~= unitDesignation then |
|
413 |
|
return |
|
414 |
|
end |
|
415 |
|
|
|
416 |
|
local overlay = healthBarFrame.overlay |
|
417 |
|
assert (overlay ~= nil) |
|
418 |
|
|
|
419 |
|
--[[ Apply health bar width changes. ]]-- |
|
420 |
|
local ratio = 1 |
|
421 |
|
if UnitExists(unitDesignation) then |
|
422 |
|
ratio = getUnitHealthRatio(unitDesignation) or 1 |
|
423 |
|
end |
|
424 |
|
ratio = math.min(math.max(0, ratio or 1), 1) |
|
425 |
|
overlay:SetPoint('BOTTOMLEFT', healthBarFrame, 'BOTTOMLEFT', 0, 0) |
|
426 |
|
overlay:SetPoint('TOPRIGHT', healthBarFrame, 'TOPRIGHT', (ratio - 1) * healthBarFrame:GetWidth(), 0) |
|
427 |
|
|
|
428 |
|
--[[ Apply health bar color changes. ]]-- |
|
429 |
|
local a = 1 |
|
430 |
|
local rangeSpell = ChoirRangeSpellName |
|
431 |
|
--[[ NOTE IsSpellInRange returns either 0, 1 or nil ]]-- |
|
432 |
|
if rangeSpell and 1 ~= IsSpellInRange(rangeSpell, unitDesignation) then |
|
433 |
|
a = 0.5 |
|
434 |
|
end |
|
435 |
|
|
|
436 |
|
if ratio <= 0.35 then |
|
437 |
|
overlay:SetVertexColor(1, 0, 0, a) |
|
438 |
|
elseif ratio <= 0.5 then |
|
439 |
|
overlay:SetVertexColor(1, 1, 0, a) |
343 |
440 |
else |
else |
344 |
|
error('invalid argument') |
|
|
441 |
|
overlay:SetVertexColor(0, 1, 0, a) |
345 |
442 |
end |
end |
|
443 |
|
|
|
444 |
|
--[[ Apply health bar text content. ]]-- |
|
445 |
|
local label = healthBarFrame.label |
|
446 |
|
assert (label ~= nil) |
|
447 |
|
|
|
448 |
|
local t |
|
449 |
|
local d = getUnitHealthDeficit(unitDesignation) or 0 |
|
450 |
|
if UnitIsDead(unitDesignation) then |
|
451 |
|
t = '(Dead)' |
|
452 |
|
elseif UnitIsGhost(unitDesignation) then |
|
453 |
|
t = '(Ghost)' |
|
454 |
|
elseif d < 0 then |
|
455 |
|
if math.abs(d) > 1000 then |
|
456 |
|
t = math.floor(d / 1000) .. ' K' |
|
457 |
|
elseif math.abs(d) > 1000000 then |
|
458 |
|
t = math.floor(d / 1000000) .. ' M' |
|
459 |
|
else |
|
460 |
|
t = tostring(math.floor(d)) |
|
461 |
|
end |
|
462 |
|
else |
|
463 |
|
t = nil |
|
464 |
|
end |
|
465 |
|
|
|
466 |
|
label:SetText(t) |
346 |
467 |
end |
end |
347 |
468 |
|
|
348 |
|
local function updateUnitButtonRoleWidget(roleWidget, unitDesignation) |
|
349 |
|
assert (roleWidget ~= nil) |
|
|
469 |
|
local function createHealthBar(unitButton, width, height) |
|
470 |
|
assert (unitButton ~= nil) |
|
471 |
|
|
|
472 |
|
assert (width ~= nil) |
|
473 |
|
assert ('number' == type(width)) |
|
474 |
|
assert (width >= 12) |
|
475 |
|
assert (width <= 288) |
|
476 |
|
|
|
477 |
|
assert (height ~= nil) |
|
478 |
|
assert ('number' == type(height)) |
|
479 |
|
assert (height >= 12) |
|
480 |
|
assert (height <= 288) |
|
481 |
|
|
|
482 |
|
local n = (unitButton:GetName() or '') .. 'HealthBarFrame' |
|
483 |
|
local healthBarFrame = CreateFrame('FRAME', n, unitButton) |
|
484 |
|
healthBarFrame:SetSize(width, height) |
|
485 |
|
|
|
486 |
|
local b = healthBarFrame:CreateTexture(n .. 'Overlay', 'OVERLAY') |
|
487 |
|
b:SetAllPoints() |
|
488 |
|
b:SetTexture("Interface\\AddOns\\choir\\share\\Minimalist.tga") |
|
489 |
|
b:SetVertexColor(getDefaultUnitButtonBarColor(), 1) |
|
490 |
|
|
|
491 |
|
local t = createLabel(healthBarFrame, UnifontRegular16) |
|
492 |
|
|
|
493 |
|
healthBarFrame.label = t |
|
494 |
|
healthBarFrame.overlay = b |
|
495 |
|
|
|
496 |
|
healthBarFrame:RegisterEvent('UNIT_COMBAT') |
|
497 |
|
healthBarFrame:RegisterEvent('UNIT_HEALTH') |
|
498 |
|
healthBarFrame:SetScript('OnEvent', healthBarEventProcessor) |
|
499 |
|
|
|
500 |
|
return healthBarFrame |
|
501 |
|
end |
|
502 |
|
|
|
503 |
|
local function headerEventProcessor(headerFrame) |
|
504 |
|
assert (headerFrame ~= nil) |
|
505 |
|
|
|
506 |
|
local label = headerFrame.label |
|
507 |
|
assert (label ~= nil) |
|
508 |
|
|
|
509 |
|
local unitButton = headerFrame:GetParent() |
|
510 |
|
assert (unitButton ~= nil) |
|
511 |
|
|
|
512 |
|
local unitDesignation = unitButton:GetAttribute('unit') |
350 |
513 |
assert (unitDesignation ~= nil) |
assert (unitDesignation ~= nil) |
351 |
514 |
|
|
352 |
|
local isTank, isHealer, isDamager = UnitGroupRolesAssigned(unitDesignation) |
|
|
515 |
|
local n |
|
516 |
|
local unitName = UnitName(unitDesignation) |
|
517 |
|
if not unitName or string.len(unitName) < 2 then |
|
518 |
|
n = unitDesignation |
|
519 |
|
else |
|
520 |
|
n = unitName |
|
521 |
|
end |
353 |
522 |
|
|
354 |
|
--[[ Corner-case for Interface >= 40000 ]]-- |
|
355 |
|
if 'string' == type(isTank) then |
|
356 |
|
local roleDesignation = isTank |
|
357 |
|
isTank = 'TANK' == roleDesignation |
|
358 |
|
isHealer = 'HEALER' == roleDesignation |
|
359 |
|
isDamager = 'DAMAGER' == roleDesignation |
|
|
523 |
|
local m = math.floor(headerFrame:GetWidth() / 16) |
|
524 |
|
local sanitizedName = string.sub(n, 1, m) |
|
525 |
|
if string.len(sanitizedName) < string.len(unitName) then |
|
526 |
|
sanitizedName = sanitizedName .. '…' |
360 |
527 |
end |
end |
361 |
528 |
|
|
362 |
|
if isTank or isHealer or isDamager then |
|
363 |
|
roleWidget:Show() |
|
364 |
|
roleWidget:SetTexCoord(getRoleTexCoord(isTank, isHealer, isDamager)) |
|
|
529 |
|
local key = GetBindingKey('CLICK ' .. unitButton:GetName() .. ':LeftButton') |
|
530 |
|
if not key then |
|
531 |
|
key = unitButton:GetAttribute('choirBindingKey') |
|
532 |
|
end |
|
533 |
|
|
|
534 |
|
local y |
|
535 |
|
if key then |
|
536 |
|
y = ' <' .. key .. '>' |
365 |
537 |
else |
else |
366 |
|
roleWidget:Hide() |
|
|
538 |
|
y = '' |
367 |
539 |
end |
end |
|
540 |
|
|
|
541 |
|
sanitizedName = sanitizedName .. y |
|
542 |
|
label:SetText(sanitizedName) |
|
543 |
|
|
|
544 |
|
local _, classDesignation = UnitClass(unitDesignation) |
|
545 |
|
local r = 1 |
|
546 |
|
local g = 1 |
|
547 |
|
local b = 1 |
|
548 |
|
if classDesignation then |
|
549 |
|
r, g, b = getClassColor(classDesignation) |
|
550 |
|
end |
|
551 |
|
label:SetTextColor(r, g, b) |
368 |
552 |
end |
end |
369 |
553 |
|
|
370 |
|
local function unitButtonEventProcessor(unitButton) |
|
|
554 |
|
local function createHeader(unitButton, width, height) |
371 |
555 |
assert (unitButton ~= nil) |
assert (unitButton ~= nil) |
372 |
556 |
|
|
373 |
|
updateUnitButtonText(unitButton) |
|
|
557 |
|
assert (width ~= nil) |
|
558 |
|
assert ('number' == type(width)) |
|
559 |
|
assert (width >= 12) |
|
560 |
|
assert (width <= 288) |
374 |
561 |
|
|
375 |
|
local bar = unitButton.bar |
|
|
562 |
|
assert (height ~= nil) |
|
563 |
|
assert ('number' == type(height)) |
|
564 |
|
assert (height >= 12) |
|
565 |
|
assert (height <= 288) |
|
566 |
|
|
|
567 |
|
local n = (unitButton:GetName() or '') .. 'HeaderFrame' |
|
568 |
|
local headerFrame = CreateFrame('FRAME', n, unitButton) |
|
569 |
|
headerFrame:SetSize(width, height) |
|
570 |
|
|
|
571 |
|
local t = createLabel(headerFrame, UnifontRegular16) |
|
572 |
|
assert (t ~= nil) |
|
573 |
|
|
|
574 |
|
headerFrame.label = t |
|
575 |
|
|
|
576 |
|
headerFrame:RegisterEvent('PARTY_CONVERTED_TO_RAID') |
|
577 |
|
headerFrame:RegisterEvent('PARTY_MEMBERS_CHANGED') |
|
578 |
|
headerFrame:RegisterEvent('PLAYER_ENTERING_WORLD') |
|
579 |
|
headerFrame:RegisterEvent('RAID_ROSTER_UPDATE') |
|
580 |
|
headerFrame:SetScript('OnEvent', headerEventProcessor) |
|
581 |
|
|
|
582 |
|
assert (headerFrame ~= nil) |
|
583 |
|
return headerFrame |
|
584 |
|
end |
|
585 |
|
|
|
586 |
|
local function unitButtonEventProcessor(unitButton, eventCategory, targetUnit, ...) |
376 |
587 |
assert (unitButton ~= nil) |
assert (unitButton ~= nil) |
|
588 |
|
assert (eventCategory ~= nil) |
|
589 |
|
|
|
590 |
|
trace(unitButton:GetName(), eventCategory, targetUnit, ...) |
377 |
591 |
|
|
378 |
592 |
local unitDesignation = unitButton:GetAttribute('unit') |
local unitDesignation = unitButton:GetAttribute('unit') |
379 |
593 |
assert (unitDesignation ~= nil) |
assert (unitDesignation ~= nil) |
|
... |
... |
local function unitButtonEventProcessor(unitButton) |
382 |
596 |
assert (string.len(unitDesignation) >= 2) |
assert (string.len(unitDesignation) >= 2) |
383 |
597 |
assert (string.len(unitDesignation) <= 32) |
assert (string.len(unitDesignation) <= 32) |
384 |
598 |
|
|
|
599 |
|
if targetUnit and targetUnit ~= unitDesignation then |
|
600 |
|
return |
|
601 |
|
end |
|
602 |
|
|
|
603 |
|
updateUnitButtonText(unitButton) |
|
604 |
|
|
|
605 |
|
local bar = unitButton.bar |
|
606 |
|
assert (unitButton ~= nil) |
|
607 |
|
|
385 |
608 |
updateUnitButtonBarOverlay(bar, unitDesignation) |
updateUnitButtonBarOverlay(bar, unitDesignation) |
386 |
609 |
updateUnitButtonBarText(bar, unitDesignation) |
updateUnitButtonBarText(bar, unitDesignation) |
387 |
|
updateUnitButtonRoleWidget(unitButton.roleWidget, unitDesignation) |
|
388 |
610 |
end |
end |
389 |
611 |
|
|
390 |
612 |
local function createInheritanceHandler(unitButton) |
local function createInheritanceHandler(unitButton) |
|
... |
... |
local function createUnitButtonTooltip(unitButton) |
454 |
676 |
end) |
end) |
455 |
677 |
end |
end |
456 |
678 |
|
|
457 |
|
local function createUnitButton(parentFrame, frameName, unit, width, height) |
|
|
679 |
|
local function createThreatWidget(unitButton, width, height) |
|
680 |
|
local t = CreateFrame('FRAME', unitButton:GetName() .. 'ThreatFrame', unitButton) |
|
681 |
|
t:SetSize(width, height) |
|
682 |
|
|
|
683 |
|
local background = createBackground(t) |
|
684 |
|
|
|
685 |
|
t:RegisterEvent('UNIT_THREAT_SITUATION_UPDATE') |
|
686 |
|
t:RegisterEvent('PLAYER_ENTERING_WORLD') |
|
687 |
|
t:SetScript('OnEvent', function(self, eventCategory, targetUnit) |
|
688 |
|
assert (eventCategory ~= nil) |
|
689 |
|
|
|
690 |
|
local u = unitButton:GetAttribute('unit') |
|
691 |
|
if u ~= targetUnit then |
|
692 |
|
return |
|
693 |
|
end |
|
694 |
|
|
|
695 |
|
local r = 0 |
|
696 |
|
local g = 0 |
|
697 |
|
local b = 0 |
|
698 |
|
local a = 0 |
|
699 |
|
local threatStatus = UnitThreatSituation(u) |
|
700 |
|
if threatStatus then |
|
701 |
|
r, g, b = GetThreatStatusColor(threatStatus) |
|
702 |
|
a = 1 |
|
703 |
|
end |
|
704 |
|
background:SetTexture(r, g, b, a) |
|
705 |
|
end) |
|
706 |
|
|
|
707 |
|
return t |
|
708 |
|
end |
|
709 |
|
|
|
710 |
|
local function createClearcastingIfNecessary(unitButton, targetFilter, optionalFilterDescriptor, width, height) |
|
711 |
|
assert (unitButton ~= nil) |
|
712 |
|
|
|
713 |
|
assert (targetFilter ~= nil) |
|
714 |
|
assert ('string' == type(targetFilter)) |
|
715 |
|
|
|
716 |
|
if not optionalFilterDescriptor then |
|
717 |
|
return |
|
718 |
|
end |
|
719 |
|
assert ('string' == type(optionalFilterDescriptor)) |
|
720 |
|
|
|
721 |
|
optionalFilterDescriptor = string.upper(optionalFilterDescriptor) |
|
722 |
|
if string.match(optionalFilterDescriptor, targetFilter) then |
|
723 |
|
local unitDesignation = unitButton:GetAttribute('unit') |
|
724 |
|
assert (unitDesignation ~= nil) |
|
725 |
|
|
|
726 |
|
targetFilter = string.upper(strtrim(targetFilter)) |
|
727 |
|
local n = unitButton:GetName() .. 'Clearcasting' .. targetFilter |
|
728 |
|
|
|
729 |
|
width = width or unitButton:GetWidth() |
|
730 |
|
|
|
731 |
|
local createSubset = ClearcastingFrame.createSubset |
|
732 |
|
assert (createSubset ~= nil) |
|
733 |
|
|
|
734 |
|
return createSubset(unitButton, n, |
|
735 |
|
unitDesignation, targetFilter, |
|
736 |
|
math.floor(width / 24), 1) |
|
737 |
|
end |
|
738 |
|
end |
|
739 |
|
|
|
740 |
|
local function createUnitButton(parentFrame, frameName, unit, optionalFilterDescriptor, width, height) |
458 |
741 |
assert (parentFrame ~= nil) |
assert (parentFrame ~= nil) |
459 |
742 |
assert (frameName ~= nil) |
assert (frameName ~= nil) |
460 |
743 |
assert (unit ~= nil) |
assert (unit ~= nil) |
461 |
744 |
|
|
462 |
|
--[[ TODO Add children buttons that are secure spell buttons on the same target as the unit button. |
|
463 |
|
-- Set override bindings to those buttons as ALT-A, CTRL-A, SHIFT-A, where A is the unit button key. |
|
464 |
|
-- The spells assigned to the buttons let be something like Cleanse, Dispel Magic or Flash Heal. |
|
465 |
|
-- That way, user may cast something without targeting or hiding the selection spoiler. |
|
466 |
|
-- The problem is that it is class dependant.]]-- |
|
467 |
745 |
local u = CreateFrame('BUTTON', frameName, parentFrame, 'SecureUnitButtonTemplate') |
local u = CreateFrame('BUTTON', frameName, parentFrame, 'SecureUnitButtonTemplate') |
468 |
746 |
|
|
469 |
747 |
createBindingKeyHandler(u) |
createBindingKeyHandler(u) |
470 |
748 |
createInheritanceHandler(u) |
createInheritanceHandler(u) |
471 |
749 |
|
|
|
750 |
|
u:SetAttribute('type', 'target') |
|
751 |
|
|
|
752 |
|
local padding = 4 |
472 |
753 |
if not width then |
if not width then |
473 |
|
width = 24 * 5 + 3 * 6 |
|
|
754 |
|
width = 16 |
474 |
755 |
end |
end |
475 |
|
assert (width >= 12 and width <= 144) |
|
|
756 |
|
assert (width >= 12 and width <= 288) |
476 |
757 |
|
|
477 |
758 |
if not height then |
if not height then |
478 |
|
height = 40 * 2 + 3 * 3 + 24 * 2 |
|
|
759 |
|
height = 12 |
479 |
760 |
end |
end |
480 |
|
assert (height >= 12 and height <= 144) |
|
|
761 |
|
assert (height >= 12 and height <= 288) |
481 |
762 |
|
|
482 |
|
u:SetSize(width, height) |
|
|
763 |
|
createUnitButtonExistanceHandler(u) |
|
764 |
|
createUnitButtonTooltip(u) |
483 |
765 |
|
|
484 |
|
local t = createLabel(u) |
|
485 |
|
t:SetPoint('BOTTOMLEFT', u, 'TOPLEFT', 4, -24 - 4) |
|
486 |
|
t:SetPoint('TOPRIGHT', u, 'TOPRIGHT', -4, -4) |
|
487 |
|
u.text = t |
|
|
766 |
|
u:SetAttribute('unit', unit) |
488 |
767 |
|
|
489 |
|
local b = createBackground(u) |
|
490 |
|
u.background = b |
|
|
768 |
|
local roleWidget = createUnitButtonRoleWidget(u) |
|
769 |
|
local headerFrame = createHeader(u, width, 24) |
|
770 |
|
local healthBarFrame = createHealthBar(u, width, 24) |
|
771 |
|
local threatWidget = createThreatWidget(u, width, 6) |
|
772 |
|
local help = createClearcastingIfNecessary(u, 'HELPFUL', optionalFilterDescriptor, width, 24) |
|
773 |
|
local harm = createClearcastingIfNecessary(u, 'HARMFUL', optionalFilterDescriptor, width, 24) |
491 |
774 |
|
|
492 |
|
local bar = createUnitButtonBar(u) |
|
493 |
|
u.bar = bar |
|
|
775 |
|
local sectionTable = {roleWidget, headerFrame, healthBarFrame, threatWidget, help, harm} |
494 |
776 |
|
|
495 |
|
local roleWidget = createUnitButtonRoleWidget(u) |
|
496 |
|
u.roleWidget = roleWidget |
|
|
777 |
|
local i = 0 |
|
778 |
|
local j = 0 |
|
779 |
|
local marginLeft = 0 |
|
780 |
|
local marginRight = 0 |
|
781 |
|
local y = 0 |
|
782 |
|
local sectionHeight = 0 |
|
783 |
|
while (i < #sectionTable) do |
|
784 |
|
i = i + 1 |
497 |
785 |
|
|
498 |
|
createUnitButtonExistanceHandler(u) |
|
499 |
|
createUnitButtonTooltip(u) |
|
|
786 |
|
local section = sectionTable[i] |
|
787 |
|
if section then |
|
788 |
|
j = j + 1 |
500 |
789 |
|
|
501 |
|
u:SetAttribute('type', 'target') |
|
502 |
|
u:SetAttribute('unit', unit) |
|
|
790 |
|
width = math.max(width, section:GetWidth()) |
|
791 |
|
sectionHeight = sectionHeight + section:GetHeight() |
|
792 |
|
|
|
793 |
|
section:SetPoint('TOPLEFT', marginLeft, y) |
|
794 |
|
section:SetPoint('BOTTOMRIGHT', u, 'TOPRIGHT', -marginRight, y - section:GetHeight()) |
|
795 |
|
y = y - section:GetHeight() - padding |
|
796 |
|
end |
|
797 |
|
end |
|
798 |
|
sectionHeight = sectionHeight + (j + 1) * padding |
|
799 |
|
height = math.max(height, sectionHeight) |
|
800 |
|
u:SetSize(width, height) |
503 |
801 |
|
|
504 |
|
u:SetScript('OnEvent', unitButtonEventProcessor) |
|
505 |
|
u:RegisterEvent('PARTY_CONVERTED_TO_RAID') |
|
506 |
|
u:RegisterEvent('PARTY_MEMBERS_CHANGED') |
|
507 |
|
u:RegisterEvent('PLAYER_ALIVE') |
|
508 |
|
u:RegisterEvent('RAID_ROSTER_UPDATE') |
|
509 |
|
u:RegisterEvent('UPDATE_BATTLEFIELD_SCORE') |
|
510 |
|
u:RegisterEvent('ADDON_LOADED') |
|
511 |
|
u:RegisterEvent('LFG_ROLE_UPDATE') |
|
512 |
|
u:RegisterEvent('UNIT_COMBAT') |
|
|
802 |
|
createBackground(u) |
513 |
803 |
|
|
514 |
804 |
assert (u ~= nil) |
assert (u ~= nil) |
515 |
805 |
return u |
return u |
|
... |
... |
local function createGroup(rootFrame, groupNumber, unitTable) |
731 |
1021 |
local unitDesignation = u[i] |
local unitDesignation = u[i] |
732 |
1022 |
assert (unitDesignation ~= nil) |
assert (unitDesignation ~= nil) |
733 |
1023 |
local memberNumber = (groupNumber - 1) * groupSize + i |
local memberNumber = (groupNumber - 1) * groupSize + i |
734 |
|
local b = createUnitButton(spoiler, 'ChoirUnitButton' .. tostring(memberNumber), unitDesignation) |
|
|
1024 |
|
local b = createUnitButton(spoiler, 'ChoirUnitButton' .. tostring(memberNumber), unitDesignation, 'HELPFUL HARMFUL', 12 * 16, 12 * 12) |
735 |
1025 |
b:SetPoint('BOTTOMLEFT', marginLeft, 0) |
b:SetPoint('BOTTOMLEFT', marginLeft, 0) |
736 |
1026 |
marginLeft = marginLeft + b:GetWidth() + padding |
marginLeft = marginLeft + b:GetWidth() + padding |
737 |
1027 |
|
|
|
... |
... |
local function createGroup(rootFrame, groupNumber, unitTable) |
752 |
1042 |
_G['BINDING_NAME_CLICK ' .. b:GetName() .. ':LeftButton'] = 'Unit ' .. tostring(i) |
_G['BINDING_NAME_CLICK ' .. b:GetName() .. ':LeftButton'] = 'Unit ' .. tostring(i) |
753 |
1043 |
|
|
754 |
1044 |
createUnitButtonSpellShortcut(b, i) |
createUnitButtonSpellShortcut(b, i) |
755 |
|
createClearcastingSubset(b) |
|
756 |
1045 |
end |
end |
757 |
|
spoiler:SetSize(marginLeft, 144 + 24) |
|
|
1046 |
|
spoiler:SetSize(marginLeft, 12 * 20) |
758 |
1047 |
spoiler:SetPoint('CENTER', 0, 12 * 6) |
spoiler:SetPoint('CENTER', 0, 12 * 6) |
759 |
1048 |
|
|
760 |
|
local title = createLabel(spoiler) |
|
|
1049 |
|
local title = createLabel(spoiler, UnifontRegular16) |
761 |
1050 |
title:SetPoint('TOPRIGHT', 0, 0) |
title:SetPoint('TOPRIGHT', 0, 0) |
762 |
1051 |
title:SetPoint('BOTTOMLEFT', spoiler, 'TOPLEFT', spoiler:GetWidth() / 2 - title:GetWidth() / 2, -24) |
title:SetPoint('BOTTOMLEFT', spoiler, 'TOPLEFT', spoiler:GetWidth() / 2 - title:GetWidth() / 2, -24) |
763 |
1052 |
title:SetText('Group ' .. tostring(groupNumber)) |
title:SetText('Group ' .. tostring(groupNumber)) |
|
... |
... |
end |
773 |
1062 |
local function arrangeEveryRaidGroupFrame(raidFrame) |
local function arrangeEveryRaidGroupFrame(raidFrame) |
774 |
1063 |
assert (raidFrame ~= nil) |
assert (raidFrame ~= nil) |
775 |
1064 |
|
|
776 |
|
local i = 0 |
|
777 |
1065 |
local t = {raidFrame:GetChildren()} |
local t = {raidFrame:GetChildren()} |
|
1066 |
|
local i = 0 |
|
1067 |
|
local j = 0 |
|
1068 |
|
local x = 0 |
778 |
1069 |
local y = 0 |
local y = 0 |
779 |
1070 |
local padding = 0 |
local padding = 0 |
|
1071 |
|
local row = 0 |
780 |
1072 |
while (i < #t) do |
while (i < #t) do |
781 |
1073 |
i = i + 1 |
i = i + 1 |
782 |
1074 |
local raidGroupFrame = t[i] |
local raidGroupFrame = t[i] |
783 |
1075 |
if raidGroupFrame and raidGroupFrame:IsShown() then |
if raidGroupFrame and raidGroupFrame:IsShown() then |
784 |
|
raidGroupFrame:SetPoint('BOTTOMLEFT', raidFrame, 'BOTTOMLEFT', 0, y) |
|
|
1076 |
|
raidGroupFrame:SetPoint('BOTTOMLEFT', raidFrame, 'BOTTOMLEFT', x, y) |
|
1077 |
|
x = math.floor(j / 4) * (raidGroupFrame:GetWidth() + padding) |
785 |
1078 |
y = y + raidGroupFrame:GetHeight() + padding |
y = y + raidGroupFrame:GetHeight() + padding |
|
1079 |
|
row = row + 1 |
|
1080 |
|
if row > 4 then |
|
1081 |
|
row = 0 |
|
1082 |
|
y = 0 |
|
1083 |
|
end |
|
1084 |
|
j = j + 1 |
786 |
1085 |
end |
end |
787 |
1086 |
end |
end |
788 |
1087 |
end |
end |
|
... |
... |
local function createRaidGroupLabel(groupFrame, groupNumber) |
839 |
1138 |
local labelWidth = 60 |
local labelWidth = 60 |
840 |
1139 |
|
|
841 |
1140 |
local groupLabel = groupFrame:CreateFontString(groupFrame:GetName() .. 'Label', 'OVERLAY') |
local groupLabel = groupFrame:CreateFontString(groupFrame:GetName() .. 'Label', 'OVERLAY') |
842 |
|
local fontObject = NumberFont_OutlineThick_Mono_Small |
|
|
1141 |
|
local fontObject = UnifontRegular16 or NumberFont_OutlineThick_Mono_Small |
843 |
1142 |
assert (fontObject ~= nil) |
assert (fontObject ~= nil) |
844 |
1143 |
groupLabel:SetFontObject(fontObject) |
groupLabel:SetFontObject(fontObject) |
845 |
1144 |
groupLabel:SetPoint('BOTTOMLEFT', groupFrame, 'BOTTOMLEFT', 0, 0) |
groupLabel:SetPoint('BOTTOMLEFT', groupFrame, 'BOTTOMLEFT', 0, 0) |
|
... |
... |
local function createRaidGroupFrame(raidFrame, groupNumber, unitSetOverride) |
874 |
1173 |
assert (#unitSetOverride == maxPartySize) |
assert (#unitSetOverride == maxPartySize) |
875 |
1174 |
end |
end |
876 |
1175 |
|
|
877 |
|
local buttonWidth = 48 |
|
878 |
|
local buttonHeight = 24 + 12 + 8 + 36 |
|
|
1176 |
|
local buttonWidth = 12 * 6 |
|
1177 |
|
local buttonHeight = 12 * 6 |
879 |
1178 |
local padding = 2 |
local padding = 2 |
880 |
1179 |
local labelWidth = 60 |
local labelWidth = 60 |
881 |
1180 |
|
|
|
... |
... |
local function createRaidGroupFrame(raidFrame, groupNumber, unitSetOverride) |
904 |
1203 |
assert (unitDesignation ~= nil) |
assert (unitDesignation ~= nil) |
905 |
1204 |
|
|
906 |
1205 |
local n = groupFrame:GetName() .. 'RaidUnitButton' .. tostring(i) |
local n = groupFrame:GetName() .. 'RaidUnitButton' .. tostring(i) |
907 |
|
local b = createUnitButton(groupFrame, n, unitDesignation, buttonWidth, buttonHeight) |
|
|
1206 |
|
local b = createUnitButton(groupFrame, n, unitDesignation, 'HARMFUL', buttonWidth, buttonHeight) |
908 |
1207 |
b:SetPoint('BOTTOMLEFT', labelWidth + (i - 1) * (padding + b:GetWidth()), 0) |
b:SetPoint('BOTTOMLEFT', labelWidth + (i - 1) * (padding + b:GetWidth()), 0) |
909 |
|
createClearcastingSubsetRaid(b) |
|
910 |
1208 |
end |
end |
911 |
1209 |
|
|
912 |
1210 |
groupFrame:RegisterEvent('PARTY_CONVERTED_TO_RAID') |
groupFrame:RegisterEvent('PARTY_CONVERTED_TO_RAID') |
|
... |
... |
local function createRaidFrame(rootFrame, spoilerHolder) |
937 |
1235 |
local maxPartySize = 5 |
local maxPartySize = 5 |
938 |
1236 |
local maxSubgroupQuantity = 8 |
local maxSubgroupQuantity = 8 |
939 |
1237 |
|
|
940 |
|
local buttonWidth = 48 |
|
941 |
|
local buttonHeight = 24 + 12 + 8 + 36 |
|
|
1238 |
|
local buttonWidth = 72 |
|
1239 |
|
local buttonHeight = 12 * 6 |
942 |
1240 |
local padding = 2 |
local padding = 2 |
943 |
1241 |
|
|
944 |
1242 |
local labelWidth = 60 |
local labelWidth = 60 |
|
... |
... |
local function createRaidFrame(rootFrame, spoilerHolder) |
946 |
1244 |
raidFrame:SetSize(labelWidth + (padding + buttonWidth) * maxPartySize, |
raidFrame:SetSize(labelWidth + (padding + buttonWidth) * maxPartySize, |
947 |
1245 |
(padding + buttonHeight) * (maxSubgroupQuantity / 2)) |
(padding + buttonHeight) * (maxSubgroupQuantity / 2)) |
948 |
1246 |
|
|
949 |
|
--[[ TODO Add any debuff indicator ]]-- |
|
950 |
1247 |
local j = 0 |
local j = 0 |
951 |
1248 |
while (j < maxSubgroupQuantity) do |
while (j < maxSubgroupQuantity) do |
952 |
1249 |
j = j + 1 |
j = j + 1 |