File choir.lua changed (mode: 100644) (index 8aae38b..9507a87) |
... |
... |
local function createClearcastingSubset(unitButton) |
29 |
29 |
|
|
30 |
30 |
--[[ TODO Track tank defensives in addition to player (healer) buffs. ]]-- |
--[[ TODO Track tank defensives in addition to player (healer) buffs. ]]-- |
31 |
31 |
local helpSubset = createSubset(unitButton, unitButton:GetName() .. 'HelpfulSubsetFrame', |
local helpSubset = createSubset(unitButton, unitButton:GetName() .. 'HelpfulSubsetFrame', |
32 |
|
unitDesignation, 'PLAYER HELPFUL', |
|
|
32 |
|
unitDesignation, 'HELPFUL', |
33 |
33 |
5, 1) |
5, 1) |
34 |
34 |
helpSubset:SetPoint('BOTTOMLEFT', 0, harmSubset:GetHeight()) |
helpSubset:SetPoint('BOTTOMLEFT', 0, harmSubset:GetHeight()) |
35 |
35 |
|
|
|
... |
... |
local function updateUnitButtonBarText(bar, unitDesignation) |
138 |
138 |
elseif UnitIsGhost(unitDesignation) then |
elseif UnitIsGhost(unitDesignation) then |
139 |
139 |
t = '(Ghost)' |
t = '(Ghost)' |
140 |
140 |
elseif d < 0 then |
elseif d < 0 then |
141 |
|
t = tostring(math.floor(d)) |
|
|
141 |
|
if math.abs(d) > 1000 then |
|
142 |
|
t = math.floor(d / 1000) .. ' K' |
|
143 |
|
elseif math.abs(d) > 1000000 then |
|
144 |
|
t = math.floor(d / 1000000) .. ' M' |
|
145 |
|
else |
|
146 |
|
t = tostring(math.floor(d)) |
|
147 |
|
end |
142 |
148 |
else |
else |
143 |
149 |
t = nil |
t = nil |
144 |
150 |
end |
end |
|
... |
... |
local function createUnitButtonBar(unitButton) |
227 |
233 |
local n = unitButton:GetName() or '' |
local n = unitButton:GetName() or '' |
228 |
234 |
local padding = 4 |
local padding = 4 |
229 |
235 |
local marginTop = 24 |
local marginTop = 24 |
230 |
|
local marginBottom = 40 * 2 + (3 * 3) |
|
|
236 |
|
local barHeight = 12 |
231 |
237 |
local bar = CreateFrame('FRAME', n .. 'Bar', unitButton) |
local bar = CreateFrame('FRAME', n .. 'Bar', unitButton) |
232 |
|
bar:SetPoint('BOTTOMLEFT', unitButton, 'BOTTOMLEFT', padding, padding + marginBottom) |
|
|
238 |
|
bar:SetPoint('BOTTOMLEFT', unitButton, 'TOPLEFT', padding, -padding - marginTop - barHeight) |
233 |
239 |
bar:SetPoint('TOPRIGHT', unitButton, 'TOPRIGHT', -padding, -padding - marginTop) |
bar:SetPoint('TOPRIGHT', unitButton, 'TOPRIGHT', -padding, -padding - marginTop) |
234 |
240 |
|
|
235 |
241 |
local b = bar:CreateTexture(bar:GetName() .. 'Overlay', 'OVERLAY') |
local b = bar:CreateTexture(bar:GetName() .. 'Overlay', 'OVERLAY') |
|
... |
... |
local function createInheritanceHandler(unitButton) |
314 |
320 |
return inheritor |
return inheritor |
315 |
321 |
end |
end |
316 |
322 |
|
|
317 |
|
local function createUnitButton(parentFrame, frameName, unit) |
|
|
323 |
|
local function createUnitButton(parentFrame, frameName, unit, width, height) |
318 |
324 |
assert (parentFrame ~= nil) |
assert (parentFrame ~= nil) |
319 |
325 |
assert (frameName ~= nil) |
assert (frameName ~= nil) |
320 |
326 |
assert (unit ~= nil) |
assert (unit ~= nil) |
|
... |
... |
local function createUnitButton(parentFrame, frameName, unit) |
331 |
337 |
createBindingKeyHandler(u) |
createBindingKeyHandler(u) |
332 |
338 |
createInheritanceHandler(u) |
createInheritanceHandler(u) |
333 |
339 |
|
|
334 |
|
u:SetSize(24 * 5 + 3 * 6, 40 * 2 + 3 * 3 + 24 * 2) |
|
|
340 |
|
if not width then |
|
341 |
|
width = 24 * 5 + 3 * 6 |
|
342 |
|
end |
|
343 |
|
assert (width >= 12 and width <= 144) |
|
344 |
|
|
|
345 |
|
if not height then |
|
346 |
|
height = 40 * 2 + 3 * 3 + 24 * 2 |
|
347 |
|
end |
|
348 |
|
assert (height >= 12 and height <= 144) |
|
349 |
|
|
|
350 |
|
u:SetSize(width, height) |
335 |
351 |
|
|
336 |
352 |
local t = createLabel(u) |
local t = createLabel(u) |
337 |
|
t:SetPoint('BOTTOMLEFT', u, 'BOTTOMLEFT', 4, u:GetHeight() - 24 - 4) |
|
|
353 |
|
t:SetPoint('BOTTOMLEFT', u, 'TOPLEFT', 4, -24 - 4) |
338 |
354 |
t:SetPoint('TOPRIGHT', u, 'TOPRIGHT', -4, -4) |
t:SetPoint('TOPRIGHT', u, 'TOPRIGHT', -4, -4) |
339 |
355 |
u.text = t |
u.text = t |
340 |
356 |
|
|
|
... |
... |
local function createUnitButton(parentFrame, frameName, unit) |
344 |
360 |
local bar = createUnitButtonBar(u) |
local bar = createUnitButtonBar(u) |
345 |
361 |
u.bar = bar |
u.bar = bar |
346 |
362 |
|
|
347 |
|
createClearcastingSubset(u) |
|
348 |
|
|
|
349 |
363 |
u:SetScript('OnEvent', unitButtonEventProcessor) |
u:SetScript('OnEvent', unitButtonEventProcessor) |
350 |
364 |
u:RegisterEvent('PARTY_CONVERTED_TO_RAID') |
u:RegisterEvent('PARTY_CONVERTED_TO_RAID') |
351 |
365 |
u:RegisterEvent('PARTY_MEMBERS_CHANGED') |
u:RegisterEvent('PARTY_MEMBERS_CHANGED') |
|
... |
... |
local function createGroup(rootFrame, groupNumber, unitTable) |
535 |
549 |
_G['BINDING_NAME_CLICK ' .. b:GetName() .. ':LeftButton'] = 'Unit ' .. tostring(i) |
_G['BINDING_NAME_CLICK ' .. b:GetName() .. ':LeftButton'] = 'Unit ' .. tostring(i) |
536 |
550 |
|
|
537 |
551 |
createUnitButtonSpellShortcut(b, i) |
createUnitButtonSpellShortcut(b, i) |
|
552 |
|
createClearcastingSubset(b) |
538 |
553 |
end |
end |
539 |
554 |
spoiler:SetSize(marginLeft, 144) |
spoiler:SetSize(marginLeft, 144) |
540 |
555 |
spoiler:SetPoint('CENTER', 0, 12 * 6) |
spoiler:SetPoint('CENTER', 0, 12 * 6) |
|
... |
... |
local function createGroup(rootFrame, groupNumber, unitTable) |
546 |
561 |
return spoiler |
return spoiler |
547 |
562 |
end |
end |
548 |
563 |
|
|
|
564 |
|
local function createRaidFrame(rootFrame, spoilerHolder) |
|
565 |
|
assert (rootFrame ~= nil) |
|
566 |
|
assert (spoilerHolder ~= nil) |
|
567 |
|
|
|
568 |
|
local maxPartySize = 5 |
|
569 |
|
local maxSubgroupQuantity = 8 |
|
570 |
|
local maxRaidSize = maxPartySize * maxSubgroupQuantity |
|
571 |
|
|
|
572 |
|
local buttonWidth = 48 |
|
573 |
|
local buttonHeight = 24 + 12 + 8 |
|
574 |
|
local padding = 2 |
|
575 |
|
|
|
576 |
|
local labelWidth = 60 |
|
577 |
|
local raidFrame = CreateFrame('FRAME', 'ChoirRaidFrame', rootFrame) |
|
578 |
|
raidFrame:SetSize(labelWidth + (padding + buttonWidth) * maxPartySize, |
|
579 |
|
(padding + buttonHeight) * (maxSubgroupQuantity + 1)) |
|
580 |
|
raidFrame:SetPoint('TOPLEFT', 0, -144) |
|
581 |
|
|
|
582 |
|
--[[ TODO Add party frame ]]-- |
|
583 |
|
--[[ TODO Add any debuff indicator ]]-- |
|
584 |
|
--[[ TODO Render only buttons for existing units ]]-- |
|
585 |
|
local memberNumber = 0 |
|
586 |
|
local j = 0 |
|
587 |
|
--[[ NOTE The extra number is for the party frame. |
|
588 |
|
-- Highly coupled with initSpoiler implementation. ]]-- |
|
589 |
|
while (j < maxSubgroupQuantity + 1) do |
|
590 |
|
j = j + 1 |
|
591 |
|
|
|
592 |
|
local groupFrame = CreateFrame('FRAME', 'ChoirRaidGroupFrame' .. tostring(j), raidFrame) |
|
593 |
|
groupFrame:SetSize(labelWidth + maxPartySize * (buttonWidth + padding), buttonHeight + padding) |
|
594 |
|
groupFrame:SetPoint('BOTTOMLEFT', 0, (j - 1) * (buttonHeight + padding)) |
|
595 |
|
|
|
596 |
|
local groupLabel = groupFrame:CreateFontString(groupFrame:GetName() .. 'Label', 'OVERLAY') |
|
597 |
|
local fontObject = NumberFont_OutlineThick_Mono_Small |
|
598 |
|
assert (fontObject ~= nil) |
|
599 |
|
groupLabel:SetFontObject(fontObject) |
|
600 |
|
groupLabel:SetPoint('BOTTOMLEFT', groupFrame, 'BOTTOMLEFT', 0, 0) |
|
601 |
|
groupLabel:SetPoint('TOPRIGHT', groupFrame, 'TOPLEFT', labelWidth, 0) |
|
602 |
|
|
|
603 |
|
local labelContent |
|
604 |
|
--[[ FIXME Update hotkey label at runtime without needing UI /reload. ]]-- |
|
605 |
|
local hotkey = GetBindingKey('CLICK ChoirSpoiler' .. tostring(j) .. ':LeftButton') |
|
606 |
|
if hotkey then |
|
607 |
|
labelContent = _G['BINDING_NAME_CLICK ChoirSpoiler' .. tostring(j) .. ':LeftButton'] |
|
608 |
|
labelContent = labelContent .. ' <' .. tostring(hotkey) .. '>' |
|
609 |
|
else |
|
610 |
|
labelContent = 'Group ' .. tostring(j) |
|
611 |
|
end |
|
612 |
|
groupLabel:SetText(labelContent) |
|
613 |
|
|
|
614 |
|
local i = 0 |
|
615 |
|
while (i < maxPartySize) do |
|
616 |
|
memberNumber = memberNumber + 1 |
|
617 |
|
|
|
618 |
|
local unitDesignation |
|
619 |
|
local groupType |
|
620 |
|
if memberNumber > maxRaidSize and memberNumber <= maxRaidSize + 5 then |
|
621 |
|
groupType = 'party' |
|
622 |
|
local partyMemberNumber = memberNumber - maxRaidSize |
|
623 |
|
if partyMemberNumber > 1 then |
|
624 |
|
unitDesignation = groupType .. tostring(memberNumber) |
|
625 |
|
else |
|
626 |
|
unitDesignation = 'player' |
|
627 |
|
end |
|
628 |
|
else |
|
629 |
|
groupType = 'raid' |
|
630 |
|
unitDesignation = groupType .. tostring(memberNumber) |
|
631 |
|
end |
|
632 |
|
|
|
633 |
|
local n = 'ChoirRaidUnitButton' .. tostring(memberNumber) |
|
634 |
|
local debug = false |
|
635 |
|
if debug then |
|
636 |
|
unitDesignation = 'player' |
|
637 |
|
end |
|
638 |
|
local b = createUnitButton(groupFrame, n, unitDesignation) |
|
639 |
|
b:SetSize(buttonWidth, buttonHeight) |
|
640 |
|
b:SetPoint('BOTTOMLEFT', labelWidth + i * (padding + b:GetWidth()), 0) |
|
641 |
|
i = i + 1 |
|
642 |
|
end |
|
643 |
|
end |
|
644 |
|
|
|
645 |
|
--[[ Given any spoiler is shown, then hide the raid frame. ]]-- |
|
646 |
|
--[[ Given all spoilers are hidden, show the raid frame. ]]-- |
|
647 |
|
local spoilerList = {spoilerHolder:GetChildren()} |
|
648 |
|
local p = 0 |
|
649 |
|
while (p < #spoilerList) do |
|
650 |
|
p = p + 1 |
|
651 |
|
local spoiler = spoilerList[p] |
|
652 |
|
|
|
653 |
|
local handler = CreateFrame('FRAME', 'ChoirRaidFrameToggleHandler' .. tostring(p), |
|
654 |
|
raidFrame, 'SecureHandlerShowHideTemplate') |
|
655 |
|
|
|
656 |
|
spoiler:SetFrameRef('ChoirRaidFrame', raidFrame) |
|
657 |
|
handler:WrapScript(spoiler, 'OnShow', [=[ |
|
658 |
|
local raidFrame = self:GetFrameRef('ChoirRaidFrame') |
|
659 |
|
if raidFrame then |
|
660 |
|
raidFrame:Hide() |
|
661 |
|
end |
|
662 |
|
]=]) |
|
663 |
|
|
|
664 |
|
handler:WrapScript(spoiler, 'OnHide', [=[ |
|
665 |
|
local raidFrame = self:GetFrameRef('ChoirRaidFrame') |
|
666 |
|
raidFrame:Show() |
|
667 |
|
|
|
668 |
|
local spoilerHolder = self:GetParent() |
|
669 |
|
local siblingList = spoilerHolder:GetChildList(newtable()) |
|
670 |
|
local i = 0 |
|
671 |
|
while (i < #siblingList) do |
|
672 |
|
i = i + 1 |
|
673 |
|
local sibling = siblingList[i] |
|
674 |
|
if sibling:IsShown() then |
|
675 |
|
raidFrame:Hide() |
|
676 |
|
break |
|
677 |
|
end |
|
678 |
|
end |
|
679 |
|
]=]) |
|
680 |
|
end |
|
681 |
|
|
|
682 |
|
return raidFrame |
|
683 |
|
end |
|
684 |
|
|
549 |
685 |
local function getRangeSpellNameSuggestion() |
local function getRangeSpellNameSuggestion() |
550 |
686 |
local _, classDesignation = UnitClass('player') |
local _, classDesignation = UnitClass('player') |
551 |
687 |
assert (classDesignation ~= nil) |
assert (classDesignation ~= nil) |
|
... |
... |
end |
611 |
747 |
local function initSpoiler(rootFrame) |
local function initSpoiler(rootFrame) |
612 |
748 |
assert (rootFrame ~= nil) |
assert (rootFrame ~= nil) |
613 |
749 |
|
|
614 |
|
createGroup(rootFrame, 1) |
|
615 |
|
createGroup(rootFrame, 2) |
|
616 |
|
createGroup(rootFrame, 3) |
|
617 |
|
createGroup(rootFrame, 4) |
|
618 |
|
createGroup(rootFrame, 5) |
|
619 |
|
createGroup(rootFrame, 6) |
|
620 |
|
createGroup(rootFrame, 7) |
|
621 |
|
createGroup(rootFrame, 8) |
|
|
750 |
|
--[[ WARNING All mutually exclusive frames must be placed under the same parent, |
|
751 |
|
-- for the spoiler toggling to work correctly. |
|
752 |
|
-- All siblings of spoiler frames will be toggled, which may not have been the intention. ]]-- |
|
753 |
|
local spoilerHolder = CreateFrame('FRAME', 'ChoirSpoilerRootFrame', rootFrame) |
|
754 |
|
spoilerHolder:SetAllPoints() |
|
755 |
|
|
|
756 |
|
createGroup(spoilerHolder, 1) |
|
757 |
|
createGroup(spoilerHolder, 2) |
|
758 |
|
createGroup(spoilerHolder, 3) |
|
759 |
|
createGroup(spoilerHolder, 4) |
|
760 |
|
createGroup(spoilerHolder, 5) |
|
761 |
|
createGroup(spoilerHolder, 6) |
|
762 |
|
createGroup(spoilerHolder, 7) |
|
763 |
|
createGroup(spoilerHolder, 8) |
622 |
764 |
|
|
623 |
765 |
--[[ TODO Add Esc key that closes the spoiler without clicking any of the children buttons ]]-- |
--[[ TODO Add Esc key that closes the spoiler without clicking any of the children buttons ]]-- |
624 |
766 |
--[[ TODO Generalize the interface to be used with any kind of child frames, |
--[[ TODO Generalize the interface to be used with any kind of child frames, |
|
... |
... |
local function initSpoiler(rootFrame) |
628 |
770 |
-- local t = env['MySavedVariableTable'] |
-- local t = env['MySavedVariableTable'] |
629 |
771 |
-- ``` |
-- ``` |
630 |
772 |
-- See http://www.iriel.org/wow/docs/SecureHeadersGuide-4.0-r1.pdf ]]-- |
-- See http://www.iriel.org/wow/docs/SecureHeadersGuide-4.0-r1.pdf ]]-- |
631 |
|
local spoilerParty = createGroup(rootFrame, 9, {'player', 'party1', 'party2', 'party3', 'party4'}) |
|
|
773 |
|
local spoilerParty = createGroup(spoilerHolder, 9, {'player', 'party1', 'party2', 'party3', 'party4'}) |
632 |
774 |
_G['BINDING_NAME_CLICK ' .. spoilerParty:GetName() .. ':LeftButton'] = 'Player party' |
_G['BINDING_NAME_CLICK ' .. spoilerParty:GetName() .. ':LeftButton'] = 'Player party' |
633 |
775 |
|
|
634 |
776 |
BINDING_HEADER_CHOIR = 'Choir' |
BINDING_HEADER_CHOIR = 'Choir' |
|
777 |
|
|
|
778 |
|
return spoilerHolder |
|
779 |
|
end |
|
780 |
|
|
|
781 |
|
local function initRaidFrame(rootFrame, spoilerHolder) |
|
782 |
|
return createRaidFrame(rootFrame, spoilerHolder) |
635 |
783 |
end |
end |
636 |
784 |
|
|
637 |
785 |
local function init(rootFrame) |
local function init(rootFrame) |
|
... |
... |
local function init(rootFrame) |
646 |
794 |
rootFrame:SetPoint('CENTER', 0, 0) |
rootFrame:SetPoint('CENTER', 0, 0) |
647 |
795 |
|
|
648 |
796 |
initRangeSpellName(rootFrame) |
initRangeSpellName(rootFrame) |
649 |
|
initSpoiler(rootFrame) |
|
|
797 |
|
local spoilerHolder = initSpoiler(rootFrame) |
|
798 |
|
initRaidFrame(rootFrame, spoilerHolder) |
650 |
799 |
|
|
651 |
800 |
trace('init') |
trace('init') |
652 |
801 |
end |
end |