Mercurial > wow > reaction
comparison classes/MultiCastButton.lua @ 174:09f7af2f53f8
Pretty totem bar textures
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Wed, 20 Oct 2010 00:41:10 +0000 |
parents | 49d49063cb79 |
children | df68b5a40490 |
comparison
equal
deleted
inserted
replaced
173:49d49063cb79 | 174:09f7af2f53f8 |
---|---|
50 All the textures for the multicast bar (arrows, empty-slot icons, etc) are part of a single | 50 All the textures for the multicast bar (arrows, empty-slot icons, etc) are part of a single |
51 texture: each texture uses SetTexCoord() to display only a slice of the textures. I suppose | 51 texture: each texture uses SetTexCoord() to display only a slice of the textures. I suppose |
52 this is to slightly optimize texture load performance, but it makes the UI code more clumsy. | 52 this is to slightly optimize texture load performance, but it makes the UI code more clumsy. |
53 | 53 |
54 Each totem button and arrow has a colored border indicating its elemental type. | 54 Each totem button and arrow has a colored border indicating its elemental type. |
55 TODO: update code to use these pretty per-slot icons, or start setting a border. | 55 |
56 TODO: | |
57 - make whether to show the colored border configurable (looks really bad with ButtonFacade:Zoomed) | |
58 - apply ButtonFacade to the flyout buttons? Or at least zoom the textures slightly? | |
59 - use a multiplier with SetTexCoord on totem bar texture? | |
56 | 60 |
57 Design Notes: | 61 Design Notes: |
58 - Only the header has a secure context. All other frames execute in its context. | 62 - Only the header has a secure context. All other frames execute in its context. |
59 | 63 |
60 - Each button is either type "spell" (summon/recall) or type "action" (totem action IDs are | 64 - Each button is either type "spell" (summon/recall) or type "action" (totem action IDs are |
147 | 151 |
148 -- flyout arrow | 152 -- flyout arrow |
149 local _arrow_openFlyout = -- function(self) | 153 local _arrow_openFlyout = -- function(self) |
150 [[ | 154 [[ |
151 local slot = self:GetAttribute("bar-idx") | 155 local slot = self:GetAttribute("bar-idx") |
156 local totemID = totemIDsBySlot[slot - (summonSlot or 0)] | |
157 if totemID == 0 then | |
158 totemID = "summon" | |
159 end | |
160 | |
152 local lastButton, lastPage | 161 local lastButton, lastPage |
153 for page, b in ipairs(flyoutChildren) do | 162 for page, b in ipairs(flyoutChildren) do |
154 b:Hide() | 163 b:Hide() |
164 b:SetAttribute("totemSlot",totemID) | |
155 if slot == summonSlot then | 165 if slot == summonSlot then |
156 local spellID = self:GetParent():GetAttribute("spell-page"..page) | 166 local spellID = self:GetParent():GetAttribute("spell-page"..page) |
157 if spellID then | 167 if spellID then |
158 b:SetAttribute("type","changePage") | 168 b:SetAttribute("type","changePage") |
159 b:SetAttribute("spell",spellID) | 169 b:SetAttribute("spell",spellID) |
160 b:Show() | 170 b:Show() |
161 lastButton = b | 171 lastButton = b |
162 lastPage = page | 172 lastPage = page |
163 end | 173 end |
164 else | 174 else |
165 local offset = summonSlot or 0 | |
166 local totemID = totemIDsBySlot[slot - offset] | |
167 local spell = select(page, 0, GetMultiCastTotemSpells(totemID) ) | 175 local spell = select(page, 0, GetMultiCastTotemSpells(totemID) ) |
168 if spell then | 176 if spell then |
169 b:SetAttribute("type","multispell") | 177 b:SetAttribute("type","multispell") |
170 b:SetAttribute("action", baseActionID + (currentPage - 1)*slotsPerPage + totemID) | 178 b:SetAttribute("action", baseActionID + (currentPage - 1)*slotsPerPage + totemID) |
171 b:SetAttribute("spell", spell) | 179 b:SetAttribute("spell", spell) |
179 local close = owner:GetFrameRef("close") | 187 local close = owner:GetFrameRef("close") |
180 if lastButton and close then | 188 if lastButton and close then |
181 close:ClearAllPoints() | 189 close:ClearAllPoints() |
182 close:SetPoint("BOTTOM",lastButton,"TOP",0,0) -- TODO: better anchoring | 190 close:SetPoint("BOTTOM",lastButton,"TOP",0,0) -- TODO: better anchoring |
183 close:Show() | 191 close:Show() |
192 control:CallMethod("UpdateFlyoutTextures",totemID) | |
184 end | 193 end |
185 | 194 |
186 flyout:ClearAllPoints() | 195 flyout:ClearAllPoints() |
187 flyout:SetPoint("BOTTOM",self,"BOTTOM",0,0) -- TODO: better anchoring | 196 flyout:SetPoint("BOTTOM",self,"BOTTOM",0,0) -- TODO: better anchoring |
188 if lastPage then | 197 if lastPage then |
222 ]] | 231 ]] |
223 | 232 |
224 | 233 |
225 -- | 234 -- |
226 -- The Blizzard totem bar textures are all actually one big texture, | 235 -- The Blizzard totem bar textures are all actually one big texture, |
227 -- with texcoord offsets | 236 -- with texcoord offsets. Shamelessly stolen from FrameXML/MultiCastActionBarFrame.lua |
228 -- | 237 -- |
229 local TOTEM_TEXTURE = "Interface\\Buttons\\UI-TotemBar" | 238 local TOTEM_TEXTURE = "Interface\\Buttons\\UI-TotemBar" |
230 local FLYOUT_UP_BUTTON_TCOORDS = { 99/128, 127/128, 84/256, 102/256 } | |
231 local FLYOUT_UP_BUTTON_HL_TCOORDS = { 72/128, 92/128, 88/256, 98/256 } | 239 local FLYOUT_UP_BUTTON_HL_TCOORDS = { 72/128, 92/128, 88/256, 98/256 } |
232 local FLYOUT_DOWN_BUTTON_TCOORDS = { 99/128, 127/128, 65/256, 83/256 } | |
233 local FLYOUT_DOWN_BUTTON_HL_TCOORDS = { 72/128, 92/128, 69/256, 79/256 } | 240 local FLYOUT_DOWN_BUTTON_HL_TCOORDS = { 72/128, 92/128, 69/256, 79/256 } |
234 local EMPTY_SLOT_TCOORDS = { 66/128, 96/128, 3/256, 33/256 } | 241 |
242 local SLOT_EMPTY_TCOORDS = { | |
243 [EARTH_TOTEM_SLOT] = { 66/128, 96/128, 3/256, 33/256 }, | |
244 [FIRE_TOTEM_SLOT] = { 67/128, 97/128, 100/256, 130/256 }, | |
245 [WATER_TOTEM_SLOT] = { 39/128, 69/128, 209/256, 239/256 }, | |
246 [AIR_TOTEM_SLOT] = { 66/128, 96/128, 36/256, 66/256 }, | |
247 } | |
248 | |
249 local SLOT_OVERLAY_TCOORDS = { | |
250 [EARTH_TOTEM_SLOT] = { 1/128, 35/128, 172/256, 206/256 }, | |
251 [FIRE_TOTEM_SLOT] = { 36/128, 70/128, 172/256, 206/256 }, | |
252 [WATER_TOTEM_SLOT] = { 1/128, 35/128, 207/256, 240/256 }, | |
253 [AIR_TOTEM_SLOT] = { 36/128, 70/128, 137/256, 171/256 }, | |
254 } | |
255 | |
256 local FLYOUT_UP_BUTTON_TCOORDS = { | |
257 ["summon"] = { 99/128, 127/128, 84/256, 102/256 }, | |
258 [EARTH_TOTEM_SLOT] = { 99/128, 127/128, 160/256, 178/256 }, | |
259 [FIRE_TOTEM_SLOT] = { 99/128, 127/128, 122/256, 140/256 }, | |
260 [WATER_TOTEM_SLOT] = { 99/128, 127/128, 199/256, 217/256 }, | |
261 [AIR_TOTEM_SLOT] = { 99/128, 127/128, 237/256, 255/256 }, | |
262 } | |
263 | |
264 local FLYOUT_DOWN_BUTTON_TCOORDS = { | |
265 ["summon"] = { 99/128, 127/128, 65/256, 83/256 }, | |
266 [EARTH_TOTEM_SLOT] = { 99/128, 127/128, 141/256, 159/256 }, | |
267 [FIRE_TOTEM_SLOT] = { 99/128, 127/128, 103/256, 121/256 }, | |
268 [WATER_TOTEM_SLOT] = { 99/128, 127/128, 180/256, 198/256 }, | |
269 [AIR_TOTEM_SLOT] = { 99/128, 127/128, 218/256, 236/256 }, | |
270 } | |
271 | |
272 local FLYOUT_TOP_TCOORDS = { | |
273 ["summon"] = { 33/128, 65/128, 1/256, 23/256 }, | |
274 [EARTH_TOTEM_SLOT] = { 0/128, 32/128, 46/256, 68/256 }, | |
275 [FIRE_TOTEM_SLOT] = { 33/128, 65/128, 46/256, 68/256 }, | |
276 [WATER_TOTEM_SLOT] = { 0/128, 32/128, 1/256, 23/256 }, | |
277 [AIR_TOTEM_SLOT] = { 0/128, 32/128, 91/256, 113/256 }, | |
278 } | |
279 | |
280 local FLYOUT_MIDDLE_TCOORDS = { | |
281 ["summon"] = { 33/128, 65/128, 23/256, 43/256 }, | |
282 [EARTH_TOTEM_SLOT] = { 0/128, 32/128, 68/256, 88/256 }, | |
283 [FIRE_TOTEM_SLOT] = { 33/128, 65/128, 68/256, 88/256 }, | |
284 [WATER_TOTEM_SLOT] = { 0/128, 32/128, 23/256, 43/256 }, | |
285 [AIR_TOTEM_SLOT] = { 0/128, 32/128, 113/256, 133/256 }, | |
286 } | |
235 | 287 |
236 local eventList = { | 288 local eventList = { |
237 "ACTIONBAR_SLOT_CHANGED", | 289 "ACTIONBAR_SLOT_CHANGED", |
238 "ACTIONBAR_UPDATE_STATE", | 290 "ACTIONBAR_UPDATE_STATE", |
239 "ACTIONBAR_UPDATE_USABLE", | 291 "ACTIONBAR_UPDATE_USABLE", |
289 end | 341 end |
290 else | 342 else |
291 local offset = bar.summonSlot and 1 or 0 | 343 local offset = bar.summonSlot and 1 or 0 |
292 local slot = SHAMAN_TOTEM_PRIORITIES[idx - offset] | 344 local slot = SHAMAN_TOTEM_PRIORITIES[idx - offset] |
293 local baseAction = barFrame:GetAttribute("baseActionID") + slot | 345 local baseAction = barFrame:GetAttribute("baseActionID") + slot |
346 self.totemSlot = slot | |
294 f:SetAttribute("type","action") | 347 f:SetAttribute("type","action") |
295 f:SetAttribute("action", baseAction + (page - 1) * NUM_MULTI_CAST_BUTTONS_PER_PAGE) | 348 f:SetAttribute("action", baseAction + (page - 1) * NUM_MULTI_CAST_BUTTONS_PER_PAGE) |
296 for i = 1, NUM_MULTI_CAST_PAGES do | 349 for i = 1, NUM_MULTI_CAST_PAGES do |
297 f:SetAttribute("action-page"..i, baseAction + (i-1) * NUM_MULTI_CAST_BUTTONS_PER_PAGE) | 350 f:SetAttribute("action-page"..i, baseAction + (i-1) * NUM_MULTI_CAST_BUTTONS_PER_PAGE) |
351 end | |
352 if not f.overlayTex then | |
353 local tx = f:CreateTexture("OVERLAY") | |
354 tx:SetTexture(TOTEM_TEXTURE) | |
355 tx:SetTexCoord(unpack(SLOT_OVERLAY_TCOORDS[self.totemSlot])) | |
356 tx:SetWidth(34) | |
357 tx:SetHeight(34) | |
358 tx:SetPoint("CENTER") | |
359 tx:Show() | |
360 f.overlayTex = tx | |
298 end | 361 end |
299 end | 362 end |
300 f:SetAttribute("bar-idx",idx) | 363 f:SetAttribute("bar-idx",idx) |
301 | 364 |
302 -- non secure scripts | 365 -- non secure scripts |
318 for _, evt in pairs(eventList) do | 381 for _, evt in pairs(eventList) do |
319 f:RegisterEvent(evt) | 382 f:RegisterEvent(evt) |
320 end | 383 end |
321 | 384 |
322 -- Set up a proxy for the icon texture for use with ButtonFacade | 385 -- Set up a proxy for the icon texture for use with ButtonFacade |
323 self.frames.icon.SetTexCoordRaw = self.frames.icon.SetTexCoord | 386 local SetTexCoordRaw = self.frames.icon.SetTexCoord |
324 self.frames.icon.SetTexCoord = function( tx, ... ) | 387 self.frames.icon.SetTexCoord = function( tx, ... ) |
325 if self:GetIconTexture() == TOTEM_TEXTURE then | 388 if self:GetIconTexture() == TOTEM_TEXTURE then |
326 tx:SetTexCoordRaw(unpack(EMPTY_SLOT_TCOORDS)) | 389 SetTexCoordRaw(tx,select(2,self:GetIconTexture())) |
327 else | 390 else |
328 tx:SetTexCoordRaw(...) | 391 SetTexCoordRaw(tx,...) |
329 end | 392 end |
330 end | 393 end |
331 | 394 |
332 -- attach to skinner | 395 -- attach to skinner |
333 bar:SkinButton(self) | 396 bar:SkinButton(self) |
334 | 397 |
335 f:Show() | 398 f:Show() |
336 | 399 |
337 -- open arrow | 400 -- open arrow and flyout background textures |
338 if idx ~= bar.recallSlot then | 401 if idx ~= bar.recallSlot then |
339 local arrow = CreateFrame("Button", nil, f, "SecureFrameTemplate") | 402 local arrow = f._arrowFrame or CreateFrame("Button", nil, f, "SecureFrameTemplate") |
403 f._arrowFrame = arrow | |
340 arrow:SetWidth(28) | 404 arrow:SetWidth(28) |
341 arrow:SetHeight(12) | 405 arrow:SetHeight(18) |
342 arrow:SetPoint("BOTTOM",self:GetFrame(),"TOP",0,0) -- TODO: better anchoring | 406 arrow:SetPoint("BOTTOM",self:GetFrame(),"TOP",0,0) -- TODO: better anchoring |
343 arrow:SetNormalTexture(TOTEM_TEXTURE) | 407 arrow:SetNormalTexture(TOTEM_TEXTURE) |
344 arrow:GetNormalTexture():SetTexCoord( unpack(FLYOUT_UP_BUTTON_TCOORDS) ) | 408 local slot = self.totemSlot or "summon" |
409 arrow:GetNormalTexture():SetTexCoord( unpack(FLYOUT_UP_BUTTON_TCOORDS[slot]) ) | |
345 arrow:SetHighlightTexture(TOTEM_TEXTURE) | 410 arrow:SetHighlightTexture(TOTEM_TEXTURE) |
346 arrow:GetHighlightTexture():SetTexCoord( unpack(FLYOUT_UP_BUTTON_HL_TCOORDS) ) | 411 arrow:GetHighlightTexture():SetTexCoord( unpack(FLYOUT_UP_BUTTON_HL_TCOORDS) ) |
347 arrow:SetAttribute("bar-idx",idx) | 412 arrow:SetAttribute("bar-idx",idx) |
348 arrow:Hide() | 413 arrow:Hide() |
349 barFrame:WrapScript(arrow, "OnClick", _arrow_openFlyout) | 414 barFrame:WrapScript(arrow, "OnClick", _arrow_openFlyout) |
354 | 419 |
355 return self | 420 return self |
356 end | 421 end |
357 | 422 |
358 function MultiCast:Destroy() | 423 function MultiCast:Destroy() |
359 local barFrame = self:GetFrame() | 424 local barFrame = self.bar:GetFrame() |
425 local f = self:GetFrame() | |
426 pcall( barFrame.UnwrapScript, barFrame, f, "OnEnter" ) -- ignore errors | |
427 if f._arrowFrame then | |
428 pcall( barFrame.UnwrapScript, barFrame, f._arrowFrame,"OnClick" ) -- ignore errors | |
429 end | |
360 Super.Destroy(self) | 430 Super.Destroy(self) |
361 end | 431 end |
362 | 432 |
363 function MultiCast:Refresh() | 433 function MultiCast:Refresh() |
364 Super.Refresh(self) | 434 Super.Refresh(self) |
412 tx = GetActionTexture(self.actionID) | 482 tx = GetActionTexture(self.actionID) |
413 end | 483 end |
414 if tx then | 484 if tx then |
415 return tx | 485 return tx |
416 else | 486 else |
417 return TOTEM_TEXTURE, unpack(EMPTY_SLOT_TCOORDS) | 487 return TOTEM_TEXTURE, unpack(SLOT_EMPTY_TCOORDS[self.totemSlot or 1]) |
418 end | 488 end |
419 end | 489 end |
420 | 490 |
421 function MultiCast:UpdateAction() | 491 function MultiCast:UpdateAction() |
422 local action = self:GetActionID() | 492 local action = self:GetActionID() |
514 | 584 |
515 local function UpdateFlyoutIcon(frame) | 585 local function UpdateFlyoutIcon(frame) |
516 local spellID = frame:GetAttribute("spell") | 586 local spellID = frame:GetAttribute("spell") |
517 if spellID == 0 or spellID == nil then | 587 if spellID == 0 or spellID == nil then |
518 frame.icon:SetTexture(TOTEM_TEXTURE) | 588 frame.icon:SetTexture(TOTEM_TEXTURE) |
519 frame.icon:SetTexCoord( unpack(EMPTY_SLOT_TCOORDS) ) | 589 local slot = tonumber(frame:GetAttribute("totemSlot")) or 1 |
590 frame.icon:SetTexCoord( unpack(SLOT_EMPTY_TCOORDS[slot]) ) | |
520 else | 591 else |
521 frame.icon:SetTexture(GetSpellTexture(GetSpellInfo(spellID))) | 592 frame.icon:SetTexture(GetSpellTexture(GetSpellInfo(spellID))) |
522 frame.icon:SetTexCoord(0,1,0,1) | 593 frame.icon:SetTexCoord(0,1,0,1) |
523 end | 594 end |
524 end | 595 end |
592 flyout:SetHeight(1) | 663 flyout:SetHeight(1) |
593 flyout:SetPoint("BOTTOM",f,"TOP",0,0) | 664 flyout:SetPoint("BOTTOM",f,"TOP",0,0) |
594 | 665 |
595 local close = CreateFrame("Button", nil, flyout, "SecureFrameTemplate") | 666 local close = CreateFrame("Button", nil, flyout, "SecureFrameTemplate") |
596 close:SetWidth(28) | 667 close:SetWidth(28) |
597 close:SetHeight(12) | 668 close:SetHeight(18) |
598 close:SetPoint("TOP") | 669 close:SetPoint("BOTTOM",flyout,"TOP") |
599 close:SetNormalTexture(TOTEM_TEXTURE) | 670 close:SetNormalTexture(TOTEM_TEXTURE) |
600 close:GetNormalTexture():SetTexCoord( unpack(FLYOUT_DOWN_BUTTON_TCOORDS) ) | 671 close:GetNormalTexture():SetTexCoord(unpack(FLYOUT_DOWN_BUTTON_TCOORDS["summon"])) |
601 close:SetHighlightTexture(TOTEM_TEXTURE) | 672 close:SetHighlightTexture(TOTEM_TEXTURE) |
602 close:GetHighlightTexture():SetTexCoord( unpack(FLYOUT_DOWN_BUTTON_HL_TCOORDS) ) | 673 close:GetHighlightTexture():SetTexCoord( unpack(FLYOUT_DOWN_BUTTON_HL_TCOORDS) ) |
603 f:SetFrameRef("close",close) | 674 f:SetFrameRef("close",close) |
604 f:WrapScript(close, "OnClick", _closeFlyout) | 675 f:WrapScript(close, "OnClick", _closeFlyout) |
676 close:Show() | |
677 | |
678 local midTx = flyout:CreateTexture("BACKGROUND") | |
679 midTx:SetWidth(32) | |
680 midTx:SetHeight(20) | |
681 midTx:SetPoint("BOTTOM") | |
682 midTx:SetTexture(TOTEM_TEXTURE) | |
683 midTx:SetTexCoord(unpack(FLYOUT_MIDDLE_TCOORDS["summon"])) | |
684 midTx:Show() | |
685 | |
686 local topTx = flyout:CreateTexture("BACKGROUND") | |
687 topTx:SetWidth(32) | |
688 topTx:SetHeight(20) | |
689 topTx:SetTexture(TOTEM_TEXTURE) | |
690 midTx:SetTexCoord(unpack(FLYOUT_TOP_TCOORDS["summon"])) | |
691 topTx:SetPoint("BOTTOM",midTx,"TOP",0,-10) | |
692 topTx:Show() | |
693 | |
694 function flyout:UpdateTextures(slot) | |
695 slot = slot or "summon" | |
696 close:GetNormalTexture():SetTexCoord(unpack(FLYOUT_DOWN_BUTTON_TCOORDS[slot])) | |
697 midTx:ClearAllPoints() | |
698 midTx:SetPoint("BOTTOM") | |
699 midTx:SetPoint("TOP",close,"BOTTOM",0,0) | |
700 midTx:SetTexCoord(unpack(FLYOUT_MIDDLE_TCOORDS[slot])) | |
701 topTx:SetTexCoord(unpack(FLYOUT_TOP_TCOORDS[slot])) | |
702 end | |
605 | 703 |
606 -- create flyout buttons | 704 -- create flyout buttons |
607 for i = 1, 10 do -- maximum 9 spells + 1 empty slot | 705 for i = 1, 10 do -- maximum 9 spells + 1 empty slot |
608 local b = CreateFrame("Button",nil,flyout,"SecureActionButtonTemplate") | 706 local b = CreateFrame("Button",nil,flyout,"SecureActionButtonTemplate") |
609 b:SetWidth(24) | 707 b:SetWidth(24) |
630 b:Show() | 728 b:Show() |
631 flyout.buttons[i] = b | 729 flyout.buttons[i] = b |
632 end | 730 end |
633 end | 731 end |
634 | 732 |
733 function f:UpdateFlyoutTextures(slot) | |
734 flyout:UpdateTextures(slot) | |
735 end | |
736 | |
635 f:Execute(_bar_init) | 737 f:Execute(_bar_init) |
636 end | 738 end |
637 | 739 |