File choir.lua changed (mode: 100644) (index aa1ed74..5ac0a5f) |
|
1 |
|
local function getDefaultUnitButtonBarColor() |
|
2 |
|
return 0, 1, 0 |
|
3 |
|
end |
|
4 |
|
|
1 |
5 |
local function createLabel(ownerFrame, fontObject) |
local function createLabel(ownerFrame, fontObject) |
2 |
6 |
assert (ownerFrame ~= nil) |
assert (ownerFrame ~= nil) |
3 |
7 |
|
|
|
... |
... |
local function createBackground(ownerFrame) |
20 |
24 |
return background |
return background |
21 |
25 |
end |
end |
22 |
26 |
|
|
|
27 |
|
local function createUnitButtonBar(self) |
|
28 |
|
assert (self ~= nil) |
|
29 |
|
|
|
30 |
|
local b = self:CreateTexture(self:GetName() .. 'Bar', 'OVERLAY') |
|
31 |
|
local padding = 4 |
|
32 |
|
b:SetPoint('BOTTOMLEFT', padding, padding) |
|
33 |
|
b:SetPoint('TOPRIGHT', -padding, -padding) |
|
34 |
|
b:SetTexture(getDefaultUnitButtonBarColor(), 1) |
|
35 |
|
|
|
36 |
|
self.bar = b |
|
37 |
|
|
|
38 |
|
return b |
|
39 |
|
end |
|
40 |
|
|
|
41 |
|
local function getUnitHealthDeficit(unitDesignation) |
|
42 |
|
assert (unitDesignation ~= nil) |
|
43 |
|
|
|
44 |
|
local m = UnitHealthMax(unitDesignation) or 0 |
|
45 |
|
local c = UnitHealth(unitDesignation) or 0 |
|
46 |
|
|
|
47 |
|
return math.abs(c) - math.abs(m) |
|
48 |
|
end |
|
49 |
|
|
|
50 |
|
local function getUnitHealthRatio(unitDesignation) |
|
51 |
|
assert (unitDesignation ~= nil) |
|
52 |
|
|
|
53 |
|
local m = math.abs(math.max(UnitHealthMax(unitDesignation) or 1, 1)) |
|
54 |
|
local c = math.abs(UnitHealth(unitDesignation) or 1) |
|
55 |
|
|
|
56 |
|
return c / m |
|
57 |
|
end |
|
58 |
|
|
|
59 |
|
local function updateUnitButtonText(self) |
|
60 |
|
assert (self ~= nil) |
|
61 |
|
|
|
62 |
|
local label = self.text |
|
63 |
|
assert (label ~= nil) |
|
64 |
|
|
|
65 |
|
local unitDesignation = self:GetAttribute('unit') |
|
66 |
|
assert (unitDesignation ~= nil) |
|
67 |
|
|
|
68 |
|
local n = UnitName(unitDesignation) or unitDesignation |
|
69 |
|
|
|
70 |
|
local key = GetBindingKey('CLICK ' .. self:GetName() .. ':LeftButton') |
|
71 |
|
if not key then |
|
72 |
|
key = self:GetAttribute('choirBindingKey') |
|
73 |
|
end |
|
74 |
|
if key then |
|
75 |
|
n = n .. ' <' .. key .. '>' |
|
76 |
|
end |
|
77 |
|
|
|
78 |
|
local d = getUnitHealthDeficit(unitDesignation) |
|
79 |
|
local t |
|
80 |
|
if UnitIsDead(unitDesignation) then |
|
81 |
|
t = n .. '\n\r' .. '(Dead)' |
|
82 |
|
elseif UnitIsGhost(unitDesignation) then |
|
83 |
|
t = n .. '\n\r' .. '(Ghost)' |
|
84 |
|
elseif d < 0 then |
|
85 |
|
t = n .. '\n\r' .. tostring(math.floor(d)) |
|
86 |
|
else |
|
87 |
|
t = n |
|
88 |
|
end |
|
89 |
|
|
|
90 |
|
label:SetText(t) |
|
91 |
|
end |
|
92 |
|
|
|
93 |
|
local function getClassColor(classDesignation) |
|
94 |
|
local t = RAID_CLASS_COLORS[classDesignation] |
|
95 |
|
if not t then |
|
96 |
|
return nil |
|
97 |
|
end |
|
98 |
|
return t['r'], t['g'], t['b'] |
|
99 |
|
end |
|
100 |
|
|
|
101 |
|
local function updateUnitButtonBar(self) |
|
102 |
|
assert (self ~= nil) |
|
103 |
|
|
|
104 |
|
local bar = self.bar |
|
105 |
|
assert (bar ~= nil) |
|
106 |
|
|
|
107 |
|
local unitDesignation = self:GetAttribute('unit') |
|
108 |
|
assert (unitDesignation ~= nil) |
|
109 |
|
|
|
110 |
|
--[[ Apply bar color update ]]-- |
|
111 |
|
local _, classDesignation = UnitClass(unitDesignation) |
|
112 |
|
local r, g, b = getClassColor(classDesignation) |
|
113 |
|
--[[ TODO Range indicator ]]-- |
|
114 |
|
local a = 1 |
|
115 |
|
if not r or not g or not b then |
|
116 |
|
r, g, b = getDefaultUnitButtonBarColor() |
|
117 |
|
end |
|
118 |
|
bar:SetTexture(r, g, b, a) |
|
119 |
|
|
|
120 |
|
--[[ Apply bar width update ]]-- |
|
121 |
|
|
|
122 |
|
self:SetAttribute('choirUnitHealthRatio', getUnitHealthRatio(unitDesignation)) |
|
123 |
|
local secureHandler = self.secureHandler |
|
124 |
|
secureHandler:Execute([=[ |
|
125 |
|
local u = self:GetFrameRef('ChoirUnitButton') |
|
126 |
|
local unitDesignation = u:GetAttribute('unit') |
|
127 |
|
|
|
128 |
|
local ratio = 1 |
|
129 |
|
if UnitExists(unitDesignation) then |
|
130 |
|
ratio = u:GetAttribute('choirUnitHealthRatio') |
|
131 |
|
end |
|
132 |
|
ratio = math.min(math.max(0, ratio), 1) |
|
133 |
|
|
|
134 |
|
local bar = self:GetFrameRef('ChoirBar') |
|
135 |
|
local padding = 4 |
|
136 |
|
bar:SetPoint('BOTTOMLEFT', self, 'BOTTOMLEFT', padding, padding) |
|
137 |
|
bar:SetPoint('TOPRIGHT', self, 'TOPLEFT', ratio * u:GetWidth() - padding, -padding) |
|
138 |
|
]=]) |
|
139 |
|
end |
|
140 |
|
|
|
141 |
|
local function unitButtonEventProcessor(self) |
|
142 |
|
updateUnitButtonText(self) |
|
143 |
|
updateUnitButtonBar(self) |
|
144 |
|
end |
|
145 |
|
|
23 |
146 |
local function createUnitButton(parentFrame, frameName, unit) |
local function createUnitButton(parentFrame, frameName, unit) |
24 |
147 |
assert (parentFrame ~= nil) |
assert (parentFrame ~= nil) |
25 |
148 |
assert (frameName ~= nil) |
assert (frameName ~= nil) |
|
... |
... |
local function createUnitButton(parentFrame, frameName, unit) |
29 |
152 |
u:SetAttribute('type', 'target') |
u:SetAttribute('type', 'target') |
30 |
153 |
u:SetAttribute('unit', unit) |
u:SetAttribute('unit', unit) |
31 |
154 |
|
|
32 |
|
u:SetSize(12 * 6, 12 * 2) |
|
|
155 |
|
u:SetSize(12 * 8, 12 * 4) |
33 |
156 |
|
|
34 |
157 |
u.text = createLabel(u) |
u.text = createLabel(u) |
35 |
158 |
|
|
36 |
159 |
local b = createBackground(u) |
local b = createBackground(u) |
37 |
|
b:SetTexture(1.0, 0.0, 0.4, 1.0) |
|
38 |
160 |
u.background = b |
u.background = b |
39 |
161 |
|
|
40 |
|
u:SetScript('OnEvent', function(self) |
|
41 |
|
assert (self ~= nil) |
|
42 |
|
local label = self.text |
|
43 |
|
assert (label ~= nil) |
|
44 |
|
local unitDesignation = self:GetAttribute('unit') |
|
45 |
|
assert (unitDesignation ~= nil) |
|
46 |
|
label:SetText(UnitName(unitDesignation) or unitDesignation) |
|
47 |
|
end) |
|
|
162 |
|
local bar = createUnitButtonBar(u) |
|
163 |
|
u.bar = bar |
|
164 |
|
|
|
165 |
|
local secureHandler = CreateFrame('BUTTON', frameName .. 'SecureHeader', u, 'SecureHandlerBaseTemplate') |
|
166 |
|
secureHandler:SetAllPoints() |
|
167 |
|
secureHandler:SetFrameRef('ChoirUnitButton', u) |
|
168 |
|
secureHandler:SetFrameRef('ChoirBar', bar) |
|
169 |
|
u.secureHandler = secureHandler |
|
170 |
|
|
|
171 |
|
u:SetScript('OnEvent', unitButtonEventProcessor) |
48 |
172 |
u:RegisterEvent('PARTY_CONVERTED_TO_RAID') |
u:RegisterEvent('PARTY_CONVERTED_TO_RAID') |
49 |
173 |
u:RegisterEvent('PARTY_MEMBERS_CHANGED') |
u:RegisterEvent('PARTY_MEMBERS_CHANGED') |
50 |
174 |
u:RegisterEvent('PLAYER_ALIVE') |
u:RegisterEvent('PLAYER_ALIVE') |
51 |
175 |
u:RegisterEvent('RAID_ROSTER_UPDATE') |
u:RegisterEvent('RAID_ROSTER_UPDATE') |
52 |
176 |
u:RegisterEvent('UPDATE_BATTLEFIELD_SCORE') |
u:RegisterEvent('UPDATE_BATTLEFIELD_SCORE') |
53 |
177 |
u:RegisterEvent('ADDON_LOADED') |
u:RegisterEvent('ADDON_LOADED') |
|
178 |
|
--[[ UNIT_HEALTH event with the current implementation does produce unnecessary calls. |
|
179 |
|
-- Optimization is desireable. Code maintanence takes priority currently. ]]-- |
|
180 |
|
u:RegisterEvent('UNIT_HEALTH') |
54 |
181 |
|
|
55 |
182 |
assert (u ~= nil) |
assert (u ~= nil) |
56 |
183 |
return u |
return u |
|
... |
... |
local function createSpoiler(spoilerParent, spoilerDesignation) |
63 |
190 |
-- the children table must be sorted and be iterated over in a specific order. |
-- the children table must be sorted and be iterated over in a specific order. |
64 |
191 |
-- #GetChildList method seems to return the children in order they were created, |
-- #GetChildList method seems to return the children in order they were created, |
65 |
192 |
-- but that might not be the case for #GetChildren variant or not at all. ]]-- |
-- but that might not be the case for #GetChildren variant or not at all. ]]-- |
66 |
|
--[[ TODO Check if it is possible to decouple the binding logic into a hooked script or something. |
|
67 |
|
-- That way the sibling and children toggling could be re-used. ]]-- |
|
68 |
193 |
spoiler:SetAttribute('_onclick', [=[ |
spoiler:SetAttribute('_onclick', [=[ |
69 |
|
local debugFlag = true |
|
70 |
|
|
|
|
194 |
|
--[[ Toggle sibling frames, which are other spoilers that contain unit buttons ]]-- |
71 |
195 |
local parentFrame = self:GetParent() |
local parentFrame = self:GetParent() |
72 |
196 |
local siblingTable = parentFrame:GetChildList(newtable()) |
local siblingTable = parentFrame:GetChildList(newtable()) |
73 |
197 |
local i = 0 |
local i = 0 |
|
... |
... |
local function createSpoiler(spoilerParent, spoilerDesignation) |
78 |
202 |
sibling:Hide() |
sibling:Hide() |
79 |
203 |
end |
end |
80 |
204 |
|
|
|
205 |
|
--[[ Apply override bindings to children which are unit buttons of a specific raid group ]]-- |
81 |
206 |
self:Show() |
self:Show() |
82 |
207 |
local j = 0 |
local j = 0 |
83 |
208 |
local childTable = self:GetChildList(newtable()) |
local childTable = self:GetChildList(newtable()) |
84 |
209 |
while (j < #childTable) do |
while (j < #childTable) do |
85 |
210 |
j = j + 1 |
j = j + 1 |
86 |
211 |
local child = childTable[j] |
local child = childTable[j] |
87 |
|
local unitDesignation = child:GetAttribute('unit') |
|
88 |
|
if unitDesignation ~= nil and UnitExists(unitDesignation) and not debugFlag then |
|
89 |
|
child:Show() |
|
90 |
|
elseif debugFlag then |
|
91 |
|
child:Show() |
|
92 |
|
else |
|
93 |
|
child:Hide() |
|
94 |
|
end |
|
95 |
|
|
|
96 |
|
local key = GetBindingKey('CLICK ChoirUnitButton' .. tostring(j) .. ':LeftButton') |
|
97 |
|
|
|
98 |
|
local actionBarSize = 12 |
|
99 |
|
if not key then |
|
100 |
|
if j >= 1 and j <= actionBarSize then |
|
101 |
|
key = GetBindingKey('ACTIONBUTTON' .. tostring(j)) |
|
102 |
|
elseif j > actionBarSize and j <= actionBarSize * 6 then |
|
103 |
|
local r = j % actionBarSize |
|
104 |
|
local n = j - r * actionBarSize |
|
105 |
|
key = GetBindingKey('MULTIACTIONBAR' .. r .. 'BUTTON' .. n) |
|
106 |
|
end |
|
107 |
|
end |
|
|
212 |
|
child:Show() |
108 |
213 |
|
|
|
214 |
|
local key = child:GetAttribute('choirBindingKey') |
109 |
215 |
if key then |
if key then |
110 |
216 |
self:SetBindingClick(true, key, child) |
self:SetBindingClick(true, key, child) |
111 |
217 |
end |
end |
|
... |
... |
local function createSpoiler(spoilerParent, spoilerDesignation) |
115 |
221 |
return spoiler |
return spoiler |
116 |
222 |
end |
end |
117 |
223 |
|
|
|
224 |
|
local function getButtonBindingKeyExplicit(buttonRef) |
|
225 |
|
assert (buttonRef ~= nil) |
|
226 |
|
|
|
227 |
|
local key = GetBindingKey('CLICK ' .. buttonRef:GetName() .. ':LeftButton') |
|
228 |
|
return key |
|
229 |
|
end |
|
230 |
|
|
|
231 |
|
local function getButtonBindingKeyDefault(buttonNumber) |
|
232 |
|
assert (buttonNumber ~= nil) |
|
233 |
|
assert ('number' == type(buttonNumber)) |
|
234 |
|
buttonNumber = math.abs(math.floor(buttonNumber)) |
|
235 |
|
|
|
236 |
|
local key |
|
237 |
|
local actionBarSize = 12 |
|
238 |
|
if buttonNumber >= 1 and buttonNumber <= actionBarSize then |
|
239 |
|
key = GetBindingKey('ACTIONBUTTON' .. tostring(buttonNumber)) |
|
240 |
|
elseif buttonNumber > actionBarSize and buttonNumber <= actionBarSize * 6 then |
|
241 |
|
local r = buttonNumber % actionBarSize |
|
242 |
|
local n = buttonNumber - r * actionBarSize |
|
243 |
|
key = GetBindingKey('MULTIACTIONBAR' .. r .. 'BUTTON' .. n) |
|
244 |
|
else |
|
245 |
|
key = nil |
|
246 |
|
end |
|
247 |
|
|
|
248 |
|
return key |
|
249 |
|
end |
|
250 |
|
|
118 |
251 |
local function createGroup(rootFrame, groupNumber, unitTable) |
local function createGroup(rootFrame, groupNumber, unitTable) |
119 |
252 |
assert (rootFrame ~= nil) |
assert (rootFrame ~= nil) |
120 |
253 |
|
|
|
... |
... |
local function createGroup(rootFrame, groupNumber, unitTable) |
140 |
273 |
assert (#u == groupSize) |
assert (#u == groupSize) |
141 |
274 |
|
|
142 |
275 |
local spoiler = createSpoiler(rootFrame, 'ChoirSpoiler' .. tostring(groupNumber)) |
local spoiler = createSpoiler(rootFrame, 'ChoirSpoiler' .. tostring(groupNumber)) |
143 |
|
spoiler:SetSize(12 * 6, 12 * 2) |
|
144 |
|
spoiler:SetPoint('CENTER', 0, 144) |
|
|
276 |
|
spoiler:SetSize(12 * 6, 12 * 4) |
|
277 |
|
spoiler:SetPoint('CENTER', 12 * 6 * 6 / -2, 144) |
145 |
278 |
|
|
146 |
279 |
local i = 0 |
local i = 0 |
147 |
|
local marginLeft = spoiler:GetWidth() |
|
|
280 |
|
local marginLeft = 0 |
148 |
281 |
local padding = 4 |
local padding = 4 |
149 |
282 |
while (i < #u) do |
while (i < #u) do |
150 |
283 |
i = i + 1 |
i = i + 1 |
|
... |
... |
local function createGroup(rootFrame, groupNumber, unitTable) |
152 |
285 |
assert (unitDesignation ~= nil) |
assert (unitDesignation ~= nil) |
153 |
286 |
local memberNumber = (groupNumber - 1) * groupSize + i |
local memberNumber = (groupNumber - 1) * groupSize + i |
154 |
287 |
local b = createUnitButton(spoiler, 'ChoirUnitButton' .. tostring(memberNumber), unitDesignation) |
local b = createUnitButton(spoiler, 'ChoirUnitButton' .. tostring(memberNumber), unitDesignation) |
155 |
|
b:SetPoint('BOTTOMLEFT', marginLeft + padding, 0) |
|
|
288 |
|
b:SetPoint('BOTTOMLEFT', marginLeft, 0) |
156 |
289 |
marginLeft = marginLeft + b:GetWidth() + padding |
marginLeft = marginLeft + b:GetWidth() + padding |
157 |
290 |
|
|
158 |
291 |
spoiler:WrapScript(b, 'OnClick', [=[ |
spoiler:WrapScript(b, 'OnClick', [=[ |
159 |
|
print('OnClick', self:GetName()) |
|
160 |
|
--[[ Assume that the parent frame is the relevant spoiler frame ]]-- |
|
|
292 |
|
--[[ Assume that parent is the spoiler frame |
|
293 |
|
-- which was created with createSpoiler and |
|
294 |
|
-- has required scripts hooked to it ]]-- |
161 |
295 |
local spoilerFrame = self:GetParent() |
local spoilerFrame = self:GetParent() |
162 |
296 |
spoilerFrame:ClearBindings() |
spoilerFrame:ClearBindings() |
163 |
297 |
spoilerFrame:Hide() |
spoilerFrame:Hide() |
164 |
298 |
]=]) |
]=]) |
165 |
299 |
b:Hide() |
b:Hide() |
|
300 |
|
|
|
301 |
|
local key = getButtonBindingKeyExplicit(b) or getButtonBindingKeyDefault(i) |
|
302 |
|
if key then |
|
303 |
|
b:SetAttribute('choirBindingKey', key) |
|
304 |
|
end |
166 |
305 |
|
|
167 |
306 |
_G['BINDING_NAME_CLICK ' .. b:GetName() .. ':LeftButton'] = 'Unit ' .. tostring(i) |
_G['BINDING_NAME_CLICK ' .. b:GetName() .. ':LeftButton'] = 'Unit ' .. tostring(i) |
168 |
307 |
end |
end |
|
... |
... |
end |
207 |
346 |
|
|
208 |
347 |
local function main() |
local function main() |
209 |
348 |
local rootFrame = CreateFrame('FRAME', 'ChoirFrame', UIParent) |
local rootFrame = CreateFrame('FRAME', 'ChoirFrame', UIParent) |
210 |
|
rootFrame:RegisterEvent('ADDON_LOADED') |
|
|
349 |
|
--[[ NOTE The add-on requires key bindings data. |
|
350 |
|
-- Therefore trigger the add-on initialization after the key bindings were loaded. ]]-- |
|
351 |
|
rootFrame:RegisterEvent('PLAYER_LOGIN') |
211 |
352 |
rootFrame:SetScript('OnEvent', init) |
rootFrame:SetScript('OnEvent', init) |
212 |
353 |
end |
end |
213 |
354 |
main() |
main() |