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 |
