GameTooltip.lua

GameTooltip.lua (9.0.2.37474; unchanged since 9.0.2.36665)
  1. --[[ Optionals:
  2. headerText - string
  3. headerColor - color
  4. wrapHeaderText - bool
  5. atLeastShowAzerite - bool
  6. fullItemDescription - bool
  7. prioritizeCurrencyOverItem - bool
  8. --]]
  9. TOOLTIP_QUEST_REWARDS_STYLE_DEFAULT = {
  10. headerText = QUEST_REWARDS,
  11. headerColor = NORMAL_FONT_COLOR,
  12. prefixBlankLineCount = 1,
  13. postHeaderBlankLineCount = 0,
  14. wrapHeaderText = true,
  15. fullItemDescription = true,
  16. }
  17. TOOLTIP_QUEST_REWARDS_STYLE_NO_HEADER = {
  18. prefixBlankLineCount = 0,
  19. postHeaderBlankLineCount = 0,
  20. fullItemDescription = true,
  21. }
  22. TOOLTIP_QUEST_REWARDS_STYLE_CONTRIBUTION = {
  23. headerText = CONTRIBUTION_REWARD_TOOLTIP_TEXT,
  24. headerColor = NORMAL_FONT_COLOR,
  25. prefixBlankLineCount = 0,
  26. postHeaderBlankLineCount = 1,
  27. wrapHeaderText = false,
  28. fullItemDescription = true,
  29. }
  30. TOOLTIP_QUEST_REWARDS_STYLE_PVP_BOUNTY = {
  31. headerText = PVP_BOUNTY_REWARD_TITLE,
  32. headerColor = NORMAL_FONT_COLOR,
  33. prefixBlankLineCount = 0,
  34. postHeaderBlankLineCount = 0,
  35. wrapHeaderText = false,
  36. fullItemDescription = true,
  37. }
  38. TOOLTIP_QUEST_REWARDS_STYLE_ISLANDS_QUEUE = {
  39. headerText = ISLAND_QUEUE_REWARD_FOR_WINNING,
  40. headerColor = NORMAL_FONT_COLOR,
  41. prefixBlankLineCount = 0,
  42. postHeaderBlankLineCount = 1,
  43. wrapHeaderText = false,
  44. fullItemDescription = true,
  45. }
  46. TOOLTIP_QUEST_REWARDS_STYLE_EMISSARY_REWARD = {
  47. headerText = QUEST_REWARDS,
  48. headerColor = NORMAL_FONT_COLOR,
  49. prefixBlankLineCount = 1,
  50. postHeaderBlankLineCount = 0,
  51. wrapHeaderText = true,
  52. atLeastShowAzerite = true,
  53. fullItemDescription = true,
  54. }
  55. TOOLTIP_QUEST_REWARDS_STYLE_CALLING_REWARD = {
  56. prefixBlankLineCount = 0,
  57. postHeaderBlankLineCount = 1,
  58. atLeastShowAzerite = true,
  59. fullItemDescription = true,
  60. }
  61. TOOLTIP_QUEST_REWARDS_PRIORITIZE_CURRENCY_OVER_ITEM = {
  62. headerText = QUEST_REWARDS,
  63. headerColor = NORMAL_FONT_COLOR,
  64. prefixBlankLineCount = 1,
  65. postHeaderBlankLineCount = 0,
  66. wrapHeaderText = true,
  67. prioritizeCurrencyOverItem = true,
  68. atLeastShowAzerite = true,
  69. fullItemDescription = true,
  70. }
  71. TOOLTIP_QUEST_REWARDS_STYLE_QUEST_CHOICE = {
  72. -- Doesn't include a header to allow individual player choice responses to set their own
  73. prefixBlankLineCount = 1,
  74. postHeaderBlankLineCount = 0,
  75. fullItemDescription = true,
  76. }
  77. TOOLTIP_QUEST_REWARDS_STYLE_NONE = {
  78. prefixBlankLineCount = 0,
  79. postHeaderBlankLineCount = 0,
  80. }
  81. function GameTooltip_UnitColor(unit)
  82. local r, g, b;
  83. if ( UnitPlayerControlled(unit) ) then
  84. if ( UnitCanAttack(unit, "player") ) then
  85. -- Hostile players are red
  86. if ( not UnitCanAttack("player", unit) ) then
  87. --[[
  88. r = 1.0;
  89. g = 0.5;
  90. b = 0.5;
  91. ]]
  92. --[[
  93. r = 0.0;
  94. g = 0.0;
  95. b = 1.0;
  96. ]]
  97. r = 1.0;
  98. g = 1.0;
  99. b = 1.0;
  100. else
  101. r = FACTION_BAR_COLORS[2].r;
  102. g = FACTION_BAR_COLORS[2].g;
  103. b = FACTION_BAR_COLORS[2].b;
  104. end
  105. elseif ( UnitCanAttack("player", unit) ) then
  106. -- Players we can attack but which are not hostile are yellow
  107. r = FACTION_BAR_COLORS[4].r;
  108. g = FACTION_BAR_COLORS[4].g;
  109. b = FACTION_BAR_COLORS[4].b;
  110. elseif ( UnitIsPVP(unit) ) then
  111. -- Players we can assist but are PvP flagged are green
  112. r = FACTION_BAR_COLORS[6].r;
  113. g = FACTION_BAR_COLORS[6].g;
  114. b = FACTION_BAR_COLORS[6].b;
  115. else
  116. -- All other players are blue (the usual state on the "blue" server)
  117. --[[
  118. r = 0.0;
  119. g = 0.0;
  120. b = 1.0;
  121. ]]
  122. r = 1.0;
  123. g = 1.0;
  124. b = 1.0;
  125. end
  126. else
  127. local reaction = UnitReaction(unit, "player");
  128. if ( reaction ) then
  129. r = FACTION_BAR_COLORS[reaction].r;
  130. g = FACTION_BAR_COLORS[reaction].g;
  131. b = FACTION_BAR_COLORS[reaction].b;
  132. else
  133. --[[
  134. r = 0.0;
  135. g = 0.0;
  136. b = 1.0;
  137. ]]
  138. r = 1.0;
  139. g = 1.0;
  140. b = 1.0;
  141. end
  142. end
  143. return r, g, b;
  144. end
  145. function GameTooltip_SetDefaultAnchor(tooltip, parent)
  146. tooltip:SetOwner(parent, "ANCHOR_NONE");
  147. tooltip:SetPoint("BOTTOMRIGHT", UIParent, "BOTTOMRIGHT", -CONTAINER_OFFSET_X - 13, CONTAINER_OFFSET_Y);
  148. end
  149. function GameTooltip_SetBasicTooltip(tooltip, text, x, y, wrap)
  150. tooltip:SetOwner(UIParent, "ANCHOR_NONE");
  151. tooltip:ClearAllPoints();
  152. tooltip:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", x, y);
  153. local r, g, b = HIGHLIGHT_FONT_COLOR:GetRGB();
  154. tooltip:SetText(text, r, g, b, 1, wrap);
  155. end
  156. function GameTooltip_ShowDisabledTooltip(tooltip, owner, text)
  157. tooltip:SetOwner(owner);
  158. local wrap = true;
  159. GameTooltip_SetTitle(tooltip, text, RED_FONT_COLOR, wrap);
  160. tooltip:Show();
  161. end
  162. function GameTooltip_AddQuestRewardsToTooltip(tooltip, questID, style)
  163. style = style or TOOLTIP_QUEST_REWARDS_STYLE_DEFAULT;
  164. if ( GetQuestLogRewardXP(questID) > 0 or GetNumQuestLogRewardCurrencies(questID) > 0 or GetNumQuestLogRewards(questID) > 0 or
  165. GetQuestLogRewardMoney(questID) > 0 or GetQuestLogRewardArtifactXP(questID) > 0 or GetQuestLogRewardHonor(questID) > 0 or
  166. GetNumQuestLogRewardSpells(questID) > 0) then
  167. if tooltip.ItemTooltip then
  168. tooltip.ItemTooltip:Hide();
  169. end
  170. GameTooltip_AddBlankLinesToTooltip(tooltip, style.prefixBlankLineCount);
  171. if style.headerText and style.headerColor then
  172. GameTooltip_AddColoredLine(tooltip, style.headerText, style.headerColor, style.wrapHeaderText);
  173. end
  174. GameTooltip_AddBlankLinesToTooltip(tooltip, style.postHeaderBlankLineCount);
  175. local hasAnySingleLineRewards, showRetrievingData = QuestUtils_AddQuestRewardsToTooltip(tooltip, questID, style);
  176. if hasAnySingleLineRewards and tooltip.ItemTooltip and tooltip.ItemTooltip:IsShown() then
  177. GameTooltip_AddBlankLinesToTooltip(tooltip, 1);
  178. if showRetrievingData then
  179. GameTooltip_AddColoredLine(tooltip, RETRIEVING_DATA, RED_FONT_COLOR);
  180. end
  181. end
  182. end
  183. end
  184. function GameTooltip_CalculatePadding(tooltip)
  185. local itemWidth, itemHeight, bottomFontStringWidth, bottomFontStringHeight = 0, 0, 0, 0;
  186. if tooltip.ItemTooltip:IsShown() then
  187. itemWidth, itemHeight = tooltip.ItemTooltip:GetSize();
  188. itemWidth = itemWidth + 9; -- extra padding for this line
  189. end
  190. if tooltip.BottomFontString and tooltip.BottomFontString:IsShown() then
  191. bottomFontStringWidth, bottomFontStringHeight = tooltip.BottomFontString:GetSize();
  192. bottomFontStringHeight = bottomFontStringHeight + 7;
  193. bottomFontStringWidth = bottomFontStringWidth + 20; -- extra width padding for this line
  194. tooltip.ItemTooltip:SetPoint("BOTTOMLEFT", tooltip.BottomFontString, "TOPLEFT", 0, 10);
  195. else
  196. tooltip.ItemTooltip:SetPoint("BOTTOMLEFT", 10, 13);
  197. end
  198. local extraWidth = math.max(itemWidth, bottomFontStringWidth);
  199. local extraHeight = itemHeight + bottomFontStringHeight;
  200. local oldPaddingWidth, oldPaddingHeight = tooltip:GetPadding();
  201. local actualTooltipWidth = tooltip:GetWidth() - oldPaddingWidth;
  202. local paddingWidth = (actualTooltipWidth <= extraWidth) and extraWidth - actualTooltipWidth or 0;
  203. local paddingHeight = 0;
  204. if extraHeight > 0 then
  205. paddingHeight = extraHeight + 5;
  206. end
  207. if(math.abs(paddingWidth - oldPaddingWidth) > 0.5 or math.abs(paddingHeight - oldPaddingHeight) > 0.5) then
  208. tooltip:SetPadding(paddingWidth, paddingHeight);
  209. end
  210. end
  211. function GameTooltip_SetBottomText(self, text, lineColor)
  212. if self.BottomFontString then
  213. self.BottomFontString:Show();
  214. self.BottomFontString:SetText(text);
  215. self.BottomFontString:SetVertexColor(lineColor:GetRGBA());
  216. end
  217. end
  218. function GameTooltip_OnLoad(self)
  219. SharedTooltip_OnLoad(self);
  220. self.needsReset = true;
  221. self.updateTooltip = TOOLTIP_UPDATE_TIME;
  222. end
  223. function GameTooltip_OnTooltipAddMoney(self, cost, maxcost)
  224. if( not maxcost ) then --We just have 1 price to display
  225. SetTooltipMoney(self, cost, nil, string.format("%s:", SELL_PRICE));
  226. else
  227. GameTooltip_AddColoredLine(self, ("%s:"):format(SELL_PRICE), HIGHLIGHT_FONT_COLOR);
  228. local indent = string.rep(" ",4)
  229. SetTooltipMoney(self, cost, nil, string.format("%s%s:", indent, MINIMUM));
  230. SetTooltipMoney(self, maxcost, nil, string.format("%s%s:", indent, MAXIMUM));
  231. end
  232. end
  233. function SetTooltipMoney(frame, money, type, prefixText, suffixText)
  234. GameTooltip_AddBlankLinesToTooltip(frame, 1);
  235. local numLines = frame:NumLines();
  236. if ( not frame.numMoneyFrames ) then
  237. frame.numMoneyFrames = 0;
  238. end
  239. if ( not frame.shownMoneyFrames ) then
  240. frame.shownMoneyFrames = 0;
  241. end
  242. local name = frame:GetName().."MoneyFrame"..frame.shownMoneyFrames+1;
  243. local moneyFrame = _G[name];
  244. if ( not moneyFrame ) then
  245. frame.numMoneyFrames = frame.numMoneyFrames+1;
  246. moneyFrame = CreateFrame("Frame", name, frame, "TooltipMoneyFrameTemplate");
  247. name = moneyFrame:GetName();
  248. MoneyFrame_SetType(moneyFrame, "STATIC");
  249. end
  250. _G[name.."PrefixText"]:SetText(prefixText);
  251. _G[name.."SuffixText"]:SetText(suffixText);
  252. if ( type ) then
  253. MoneyFrame_SetType(moneyFrame, type);
  254. end
  255. --We still have this variable offset because many AddOns use this function. The money by itself will be unaligned if we do not use this.
  256. local xOffset;
  257. if ( prefixText ) then
  258. xOffset = 4;
  259. else
  260. xOffset = 0;
  261. end
  262. moneyFrame:SetPoint("LEFT", frame:GetName().."TextLeft"..numLines, "LEFT", xOffset, 0);
  263. moneyFrame:Show();
  264. if ( not frame.shownMoneyFrames ) then
  265. frame.shownMoneyFrames = 1;
  266. else
  267. frame.shownMoneyFrames = frame.shownMoneyFrames+1;
  268. end
  269. MoneyFrame_Update(moneyFrame:GetName(), money);
  270. local moneyFrameWidth = moneyFrame:GetWidth();
  271. if ( frame:GetMinimumWidth() < moneyFrameWidth ) then
  272. frame:SetMinimumWidth(moneyFrameWidth);
  273. end
  274. frame.hasMoney = 1;
  275. end
  276. function GameTooltip_ClearMoney(self)
  277. if ( not self.shownMoneyFrames ) then
  278. return;
  279. end
  280. local moneyFrame;
  281. for i=1, self.shownMoneyFrames do
  282. moneyFrame = _G[self:GetName().."MoneyFrame"..i];
  283. if(moneyFrame) then
  284. moneyFrame:Hide();
  285. MoneyFrame_SetType(moneyFrame, "STATIC");
  286. end
  287. end
  288. self.shownMoneyFrames = nil;
  289. end
  290. GAME_TOOLTIP_BACKDROP_STYLE_EMBEDDED = {
  291. -- Nothing
  292. };
  293. GAME_TOOLTIP_BACKDROP_STYLE_AZERITE_ITEM = {
  294. bgFile = "Interface/Tooltips/UI-Tooltip-Background-Azerite",
  295. edgeFile = "Interface/Tooltips/UI-Tooltip-Border-Azerite",
  296. tile = true,
  297. tileEdge = false,
  298. tileSize = 16,
  299. edgeSize = 19,
  300. insets = { left = 4, right = 4, top = 4, bottom = 4 },
  301. backdropBorderColor = TOOLTIP_DEFAULT_COLOR,
  302. backdropColor = WHITE_FONT_COLOR,
  303. overlayAtlasTop = "AzeriteTooltip-Topper";
  304. overlayAtlasTopScale = .75,
  305. overlayAtlasTopYOffset = 1;
  306. overlayAtlasBottom = "AzeriteTooltip-Bottom";
  307. overlayAtlasBottomYOffset = 2;
  308. padding = { left = 3, right = 3, top = 3, bottom = 3 },
  309. };
  310. GAME_TOOLTIP_BACKDROP_STYLE_CORRUPTED_ITEM = {
  311. bgFile = "Interface/Tooltips/UI-Tooltip-Background-Corrupted",
  312. edgeFile = "Interface/Tooltips/UI-Tooltip-Border-Corrupted",
  313. tile = true,
  314. tileEdge = false,
  315. tileSize = 16,
  316. edgeSize = 19,
  317. insets = { left = 4, right = 4, top = 4, bottom = 4 },
  318. backdropBorderColor = TOOLTIP_DEFAULT_COLOR,
  319. backdropColor = WHITE_FONT_COLOR,
  320. overlayAtlasTop = "Nzoth-tooltip-topper";
  321. overlayAtlasTopScale = .75,
  322. overlayAtlasTopYOffset = -2;
  323. padding = { left = 3, right = 3, top = 3, bottom = 3 },
  324. };
  325. GAME_TOOLTIP_BACKDROP_STYLE_RUNEFORGE_LEGENDARY = {
  326. bgFile = "Interface/Tooltips/UI-Tooltip-Background-Maw",
  327. edgeFile = "Interface/Tooltips/UI-Tooltip-Border-Maw",
  328. tile = true,
  329. tileEdge = false,
  330. tileSize = 16,
  331. edgeSize = 19,
  332. insets = { left = 4, right = 4, top = 4, bottom = 4 },
  333. backdropBorderColor = TOOLTIP_DEFAULT_COLOR,
  334. backdropColor = WHITE_FONT_COLOR,
  335. overlayAtlasTop = "Maw-tooltip-topper";
  336. overlayAtlasTopScale = .75,
  337. overlayAtlasTopYOffset = -2;
  338. padding = { left = 3, right = 3, top = 3, bottom = 3 },
  339. };
  340. GAME_TOOLTIP_TEXTUREKIT_BACKDROP_STYLES = {
  341. ["jailerstower"] = GAME_TOOLTIP_BACKDROP_STYLE_RUNEFORGE_LEGENDARY;
  342. };
  343. function GameTooltip_OnHide(self)
  344. self.needsReset = true;
  345. SharedTooltip_SetBackdropStyle(self, self.IsEmbedded and GAME_TOOLTIP_BACKDROP_STYLE_EMBEDDED or TOOLTIP_BACKDROP_STYLE_DEFAULT);
  346. GameTooltip_ClearMoney(self);
  347. GameTooltip_ClearStatusBars(self);
  348. GameTooltip_ClearProgressBars(self);
  349. GameTooltip_ClearWidgetSet(self);
  350. if ( self.shoppingTooltips ) then
  351. for _, frame in pairs(self.shoppingTooltips) do
  352. frame:Hide();
  353. end
  354. end
  355. self.comparing = false;
  356. ShoppingTooltip1:Hide();
  357. ShoppingTooltip2:Hide();
  358. if (BattlePetTooltip) then
  359. BattlePetTooltip:Hide();
  360. end
  361. if self.ItemTooltip then
  362. self.ItemTooltip:Hide();
  363. end
  364. self:SetPadding(0, 0, 0, 0);
  365. end
  366. function GameTooltip_CycleSecondaryComparedItem(self)
  367. GameTooltip_AdvanceSecondaryCompareItem(self);
  368. local shoppingTooltip1, shoppingTooltip2 = unpack(self.shoppingTooltips);
  369. if ( shoppingTooltip1:IsShown() ) then
  370. GameTooltip_ShowCompareItem(self);
  371. end
  372. end
  373. function GameTooltip_OnUpdate(self, elapsed)
  374. if self.recalculatePadding then
  375. self.recalculatePadding = nil;
  376. GameTooltip_CalculatePadding(self);
  377. end
  378. -- Only update every TOOLTIP_UPDATE_TIME seconds
  379. self.updateTooltip = self.updateTooltip - elapsed;
  380. if ( self.updateTooltip > 0 ) then
  381. return;
  382. end
  383. self.updateTooltip = TOOLTIP_UPDATE_TIME;
  384. local shoppingTooltip1 = self.shoppingTooltips[1];
  385. if ( not shoppingTooltip1:IsShown() ) then
  386. self.needsReset = true;
  387. end
  388. local owner = self:GetOwner();
  389. if ( owner and owner.UpdateTooltip ) then
  390. owner:UpdateTooltip();
  391. elseif self.UpdateTooltip then
  392. self:UpdateTooltip();
  393. end
  394. end
  395. function GameTooltip_HideBattlePetTooltip()
  396. if BattlePetTooltip then
  397. BattlePetTooltip:Hide();
  398. end
  399. end
  400. function GameTooltip_HideShoppingTooltips(self)
  401. local shoppingTooltip1, shoppingTooltip2 = unpack(self.shoppingTooltips);
  402. shoppingTooltip1:Hide();
  403. shoppingTooltip2:Hide()
  404. end
  405. function GameTooltip_OnTooltipSetUnit(self)
  406. if self:IsUnit("mouseover") then
  407. _G[self:GetName().."TextLeft1"]:SetTextColor(GameTooltip_UnitColor("mouseover"));
  408. end
  409. GameTooltip_HideBattlePetTooltip();
  410. end
  411. function GameTooltip_UpdateStyle(self)
  412. local backdropStyle = TOOLTIP_BACKDROP_STYLE_DEFAULT;
  413. local _, itemLink = self:GetItem();
  414. if itemLink then
  415. if C_AzeriteEmpoweredItem.IsAzeriteEmpoweredItemByID(itemLink) or C_AzeriteItem.IsAzeriteItemByID(itemLink) then
  416. backdropStyle = GAME_TOOLTIP_BACKDROP_STYLE_AZERITE_ITEM;
  417. elseif IsCorruptedItem(itemLink) then
  418. backdropStyle = GAME_TOOLTIP_BACKDROP_STYLE_CORRUPTED_ITEM;
  419. end
  420. end
  421. SharedTooltip_SetBackdropStyle(self, backdropStyle);
  422. end
  423. function GameTooltip_OnTooltipSetItem(self)
  424. if IsModifiedClick("COMPAREITEMS") or (GetCVarBool("alwaysCompareItems") and not self:IsEquippedItem()) then
  425. GameTooltip_ShowCompareItem(self);
  426. else
  427. GameTooltip_HideShoppingTooltips(self);
  428. end
  429. GameTooltip_HideBattlePetTooltip();
  430. GameTooltip_UpdateStyle(self);
  431. end
  432. function GameTooltip_OnTooltipSetShoppingItem(self)
  433. GameTooltip_UpdateStyle(self);
  434. end
  435. function GameTooltip_OnTooltipSetSpell(self)
  436. if (not IsModifiedClick("COMPAREITEMS") and not GetCVarBool("alwaysCompareItems")) or not GameTooltip_ShowCompareSpell(self) then
  437. GameTooltip_HideShoppingTooltips(self);
  438. end
  439. GameTooltip_HideBattlePetTooltip();
  440. end
  441. function GameTooltip_InitializeComparisonTooltips(self, anchorFrame)
  442. if not self then
  443. self = GameTooltip;
  444. end
  445. anchorFrame = anchorFrame or self;
  446. if self.needsReset then
  447. self:ResetSecondaryCompareItem();
  448. GameTooltip_AdvanceSecondaryCompareItem(self);
  449. self.needsReset = false;
  450. end
  451. return self, anchorFrame, unpack(self.shoppingTooltips);
  452. end
  453. function GameTooltip_AnchorComparisonTooltips(self, anchorFrame, shoppingTooltip1, shoppingTooltip2, primaryItemShown, secondaryItemShown)
  454. local sideAnchorFrame = anchorFrame;
  455. if anchorFrame.IsEmbedded then
  456. sideAnchorFrame = anchorFrame:GetParent():GetParent();
  457. end
  458. local leftPos = sideAnchorFrame:GetLeft();
  459. local rightPos = sideAnchorFrame:GetRight();
  460. local selfLeftPos = self:GetLeft();
  461. local selfRightPos = self:GetRight();
  462. -- if we get the Left, we have the Right
  463. if ( leftPos and selfLeftPos) then
  464. leftPos = math.min(selfLeftPos, leftPos);-- get the left most bound
  465. rightPos = math.max(selfRightPos, rightPos);-- get the right most bound
  466. else
  467. leftPos = leftPos or selfLeftPos or 0;
  468. rightPos = rightPos or selfRightPos or 0;
  469. end
  470. -- sometimes the sideAnchorFrame is an actual tooltip, and sometimes it's a script region, so make sure we're getting the actual anchor type
  471. local anchorType = sideAnchorFrame.GetAnchorType and sideAnchorFrame:GetAnchorType() or self:GetAnchorType();
  472. local totalWidth = 0;
  473. if ( primaryItemShown ) then
  474. totalWidth = totalWidth + shoppingTooltip1:GetWidth();
  475. end
  476. if ( secondaryItemShown ) then
  477. totalWidth = totalWidth + shoppingTooltip2:GetWidth();
  478. end
  479. local rightDist = 0;
  480. local screenWidth = GetScreenWidth();
  481. rightDist = screenWidth - rightPos;
  482. -- find correct side
  483. local side;
  484. if ( anchorType and (totalWidth < leftPos) and (anchorType == "ANCHOR_LEFT" or anchorType == "ANCHOR_TOPLEFT" or anchorType == "ANCHOR_BOTTOMLEFT") ) then
  485. side = "left";
  486. elseif ( anchorType and (totalWidth < rightDist) and (anchorType == "ANCHOR_RIGHT" or anchorType == "ANCHOR_TOPRIGHT" or anchorType == "ANCHOR_BOTTOMRIGHT") ) then
  487. side = "right";
  488. elseif ( rightDist < leftPos ) then
  489. side = "left";
  490. else
  491. side = "right";
  492. end
  493. -- see if we should slide the tooltip
  494. if ( totalWidth > 0 and (anchorType and anchorType ~= "ANCHOR_PRESERVE") ) then --we never slide a tooltip with a preserved anchor
  495. local slideAmount = 0;
  496. if ( (side == "left") and (totalWidth > leftPos) ) then
  497. slideAmount = totalWidth - leftPos;
  498. elseif ( (side == "right") and (rightPos + totalWidth) > screenWidth ) then
  499. slideAmount = screenWidth - (rightPos + totalWidth);
  500. end
  501. if (slideAmount ~= 0) then -- if we calculated a slideAmount, we need to slide
  502. if ( sideAnchorFrame.SetAnchorType ) then
  503. sideAnchorFrame:SetAnchorType(anchorType, slideAmount, 0);
  504. else
  505. self:SetAnchorType(anchorType, slideAmount, 0);
  506. end
  507. end
  508. end
  509. if ( secondaryItemShown ) then
  510. shoppingTooltip2:SetOwner(self, "ANCHOR_NONE");
  511. shoppingTooltip2:ClearAllPoints();
  512. shoppingTooltip1:SetOwner(self, "ANCHOR_NONE");
  513. shoppingTooltip1:ClearAllPoints();
  514. shoppingTooltip1:SetPoint("TOP", anchorFrame, 0, -10);
  515. shoppingTooltip2:SetPoint("TOP", anchorFrame, 0, -10);
  516. if ( side and side == "left" ) then
  517. shoppingTooltip1:SetPoint("RIGHT", sideAnchorFrame, "LEFT");
  518. else
  519. shoppingTooltip2:SetPoint("LEFT", sideAnchorFrame, "RIGHT");
  520. end
  521. if ( side and side == "left" ) then
  522. shoppingTooltip2:SetPoint("TOPRIGHT", shoppingTooltip1, "TOPLEFT");
  523. else
  524. shoppingTooltip1:SetPoint("TOPLEFT", shoppingTooltip2, "TOPRIGHT");
  525. end
  526. else
  527. shoppingTooltip1:SetOwner(self, "ANCHOR_NONE");
  528. shoppingTooltip1:ClearAllPoints();
  529. shoppingTooltip1:SetPoint("TOP", anchorFrame, 0, -10);
  530. if ( side and side == "left" ) then
  531. shoppingTooltip1:SetPoint("RIGHT", sideAnchorFrame, "LEFT");
  532. else
  533. shoppingTooltip1:SetPoint("LEFT", sideAnchorFrame, "RIGHT");
  534. end
  535. shoppingTooltip2:Hide();
  536. end
  537. end
  538. function GameTooltip_ShowCompareSpell(self, anchorFrame)
  539. local azeritePowerID, owningItemLink = self:GetAzeritePowerID();
  540. if not azeritePowerID or not owningItemLink then
  541. return false;
  542. end
  543. local owningItemSource = AzeriteEmpoweredItemDataSource:CreateFromFromItemLink(owningItemLink);
  544. local sourceItem = owningItemSource:GetItem();
  545. if not sourceItem:IsItemDataCached() then
  546. -- We'll try again later
  547. return false;
  548. end
  549. local equippedItemLocation = ItemLocation:CreateFromEquipmentSlot(sourceItem:GetInventoryType());
  550. if not C_Item.DoesItemExist(equippedItemLocation) or not C_AzeriteEmpoweredItem.IsAzeriteEmpoweredItem(equippedItemLocation) then
  551. return false;
  552. end
  553. local equippedItemSource = AzeriteEmpoweredItemDataSource:CreateFromItemLocation(equippedItemLocation);
  554. local equippedItem = equippedItemSource:GetItem(equippedItemLocation);
  555. if not equippedItem:IsItemDataCached() then
  556. -- We'll try again later
  557. return false;
  558. end
  559. local powerTierIndex = AzeriteUtil.FindAzeritePowerTier(owningItemSource, azeritePowerID);
  560. if not powerTierIndex then
  561. return false;
  562. end
  563. local comparisonPowerID = AzeriteUtil.GetSelectedAzeritePowerInTier(equippedItemSource, powerTierIndex);
  564. if not comparisonPowerID then
  565. return false;
  566. end
  567. local tooltip, anchorFrame, shoppingTooltip1, shoppingTooltip2 = GameTooltip_InitializeComparisonTooltips(self, anchorFrame);
  568. local itemID = equippedItem:GetItemID();
  569. local itemLevel = equippedItem:GetCurrentItemLevel();
  570. shoppingTooltip1:SetAzeritePower(itemID, itemLevel, comparisonPowerID);
  571. local primaryItemShown = true;
  572. local secondaryItemShown = false;
  573. GameTooltip_AnchorComparisonTooltips(tooltip, anchorFrame, shoppingTooltip1, shoppingTooltip2, primaryItemShown, secondaryItemShown);
  574. shoppingTooltip1:SetCompareAzeritePower(itemID, itemLevel, comparisonPowerID);
  575. shoppingTooltip1:Show();
  576. return true;
  577. end
  578. function GameTooltip_ShowCompareItem(self, anchorFrame)
  579. local tooltip, anchorFrame, shoppingTooltip1, shoppingTooltip2 = GameTooltip_InitializeComparisonTooltips(self, anchorFrame);
  580. local primaryItemShown, secondaryItemShown = shoppingTooltip1:SetCompareItem(shoppingTooltip2, tooltip);
  581. GameTooltip_AnchorComparisonTooltips(tooltip, anchorFrame, shoppingTooltip1, shoppingTooltip2, primaryItemShown, secondaryItemShown);
  582. -- We have to call this again because :SetOwner clears the tooltip.
  583. shoppingTooltip1:SetCompareItem(shoppingTooltip2, tooltip);
  584. shoppingTooltip1:Show();
  585. end
  586. function GameTooltip_AdvanceSecondaryCompareItem(self)
  587. if ( not self ) then
  588. self = GameTooltip;
  589. end
  590. if ( GetCVarBool("allowCompareWithToggle") ) then
  591. self:AdvanceSecondaryCompareItem();
  592. end
  593. end
  594. function GameTooltip_ClearStatusBars(self)
  595. if self.statusBarPool then
  596. self.statusBarPool:ReleaseAll();
  597. end
  598. end
  599. function GameTooltip_ShowStatusBar(self, min, max, value, text)
  600. if not self.statusBarPool then
  601. self.statusBarPool = CreateFramePool("STATUSBAR", self, "TooltipStatusBarTemplate");
  602. else
  603. GameTooltip_ClearStatusBars(self);
  604. end
  605. GameTooltip_AddStatusBar(self, min, max, value, text);
  606. end
  607. function GameTooltip_AddStatusBar(self, min, max, value, text)
  608. GameTooltip_AddBlankLinesToTooltip(self, 1);
  609. local numLines = self:NumLines();
  610. local statusBar = self.statusBarPool:Acquire();
  611. if ( not text ) then
  612. text = "";
  613. end
  614. statusBar.Text:SetText(text);
  615. statusBar:SetMinMaxValues(min, max);
  616. statusBar:SetValue(value);
  617. statusBar:Show();
  618. statusBar:SetPoint("LEFT", self:GetName().."TextLeft"..numLines, "LEFT", 0, -2);
  619. statusBar:SetPoint("RIGHT", self, "RIGHT", -9, 0);
  620. statusBar:Show();
  621. self:SetMinimumWidth(140);
  622. end
  623. function GameTooltip_ClearProgressBars(self)
  624. if self.progressBarPool then
  625. self.progressBarPool:ReleaseAll();
  626. end
  627. end
  628. function GameTooltip_ShowProgressBar(self, min, max, value, text)
  629. if not self.progressBarPool then
  630. self.progressBarPool = CreateFramePool("FRAME", self, "TooltipProgressBarTemplate");
  631. else
  632. GameTooltip_ClearProgressBars(self);
  633. end
  634. GameTooltip_AddProgressBar(self, min, max, value, text);
  635. end
  636. function GameTooltip_AddProgressBar(self, min, max, value, text)
  637. local progressBar = self.progressBarPool:Acquire();
  638. progressBar.Bar.Label:SetText(text);
  639. progressBar.Bar:SetMinMaxValues(min, max);
  640. progressBar.Bar:SetValue(value);
  641. progressBar:SetAlpha(1);
  642. GameTooltip_InsertFrame(self, progressBar);
  643. end
  644. function GameTooltip_ShowHyperlink(self, hyperlinkString, classID, specID, clearTooltip)
  645. local questRewardID = ExtractQuestRewardID(hyperlinkString);
  646. if questRewardID then
  647. -- quest reward hyperlinks are handled in lua
  648. GameTooltip_AddQuestRewardsToTooltip(self, questRewardID, TOOLTIP_QUEST_REWARDS_STYLE_NO_HEADER);
  649. else
  650. self:SetHyperlink(hyperlinkString, classID, specID, clearTooltip);
  651. end
  652. end
  653. local function WidgetLayout(widgetContainer, sortedWidgets)
  654. DefaultWidgetLayout(widgetContainer, sortedWidgets);
  655. local parentHeight = widgetContainer:GetHeight() + 10;
  656. widgetContainer:GetParent():SetHeight(parentHeight);
  657. widgetContainer.shownWidgetCount = #sortedWidgets;
  658. end
  659. function GameTooltip_AddWidgetSet(self, widgetSetID)
  660. if not widgetSetID then
  661. return;
  662. end
  663. if not self.widgetContainer then
  664. self.widgetFrame = CreateFrame("FRAME", nil, self, "WidgetOffsetContainerTemplate");
  665. self.widgetContainer = self.widgetFrame.WidgetContainer;
  666. self.widgetContainer.verticalAnchorPoint = "TOPLEFT";
  667. self.widgetContainer.verticalRelativePoint = "BOTTOMLEFT";
  668. self.widgetContainer.showAndHideOnWidgetSetRegistration = false;
  669. self.widgetContainer.disableWidgetTooltips = true;
  670. self.widgetContainer:Hide();
  671. end
  672. self.widgetContainer:RegisterForWidgetSet(widgetSetID, WidgetLayout);
  673. if self.widgetContainer.shownWidgetCount > 0 then
  674. GameTooltip_InsertFrame(self, self.widgetContainer);
  675. end
  676. end
  677. function GameTooltip_ClearWidgetSet(self)
  678. if self.widgetContainer then
  679. self.widgetContainer:UnregisterForWidgetSet();
  680. end
  681. end
  682. function GameTooltip_Hide()
  683. -- Used for XML OnLeave handlers
  684. GameTooltip:Hide();
  685. GameTooltip_HideBattlePetTooltip();
  686. end
  687. function GameTooltip_HideResetCursor()
  688. GameTooltip:Hide();
  689. ResetCursor();
  690. end
  691. function EmbeddedItemTooltip_UpdateSize(self)
  692. local itemTooltipExtraBorderHeight = 22;
  693. if ( self.Tooltip:IsShown() ) then
  694. local width = self.Tooltip:GetWidth() + self.Icon:GetWidth();
  695. local height = math.max(self.Tooltip:GetHeight() - itemTooltipExtraBorderHeight, self.Icon:GetHeight());
  696. self:SetSize(width, height);
  697. elseif ( self.FollowerTooltip:IsShown() ) then
  698. self:SetSize(self.FollowerTooltip:GetSize());
  699. end
  700. end
  701. function EmbeddedItemTooltip_OnTooltipSetItem(self)
  702. if (self.itemID and not self.itemTextureSet) then
  703. local _, _, _, _, _, _, _, _, _, itemTexture = GetItemInfo(self.itemID);
  704. if (itemTexture) then
  705. self.Icon:SetTexture(itemTexture);
  706. end
  707. end
  708. end
  709. function EmbeddedItemTooltip_Clear(self)
  710. self.Icon:Hide();
  711. self.IconBorder:Hide();
  712. self.Tooltip:Hide();
  713. self.FollowerTooltip:Hide();
  714. end
  715. function EmbeddedItemTooltip_PrepareForItem(self)
  716. EmbeddedItemTooltip_Clear(self);
  717. self.Icon:Show();
  718. self.IconBorder:Show();
  719. self.Tooltip:Show();
  720. end
  721. function EmbeddedItemTooltip_PrepareForSpell(self)
  722. EmbeddedItemTooltip_Clear(self);
  723. self.Icon:Show();
  724. self.Tooltip:Show();
  725. end
  726. function EmbeddedItemTooltip_PrepareForFollower(self)
  727. EmbeddedItemTooltip_Clear(self);
  728. self.FollowerTooltip:Show();
  729. end
  730. function EmbeddedItemTooltip_SetItemByID(self, id, count)
  731. self.itemID = id;
  732. self.spellID = nil;
  733. local itemName, _, quality, _, _, _, _, _, _, itemTexture = GetItemInfo(id);
  734. self:Show();
  735. EmbeddedItemTooltip_PrepareForItem(self);
  736. self.Tooltip:SetOwner(self, "ANCHOR_NONE");
  737. self.Tooltip:SetItemByID(id);
  738. SetItemButtonQuality(self, quality, id);
  739. SetItemButtonCount(self, count or 1);
  740. self.Icon:SetTexture(itemTexture);
  741. self.itemTextureSet = (itemTexture ~= nil);
  742. self.Tooltip:SetPoint("TOPLEFT", self.Icon, "TOPRIGHT", 0, 10);
  743. EmbeddedItemTooltip_UpdateSize(self);
  744. self:GetParent().recalculatePadding = true;
  745. end
  746. function EmbeddedItemTooltip_SetItemByQuestReward(self, questLogIndex, questID, rewardType)
  747. if not questLogIndex then
  748. return false;
  749. end
  750. rewardType = rewardType or "reward";
  751. local getterFunc;
  752. if rewardType == "choice" then
  753. getterFunc = GetQuestLogChoiceInfo;
  754. else
  755. getterFunc = GetQuestLogRewardInfo;
  756. end
  757. local itemName, itemTexture, quantity, quality, isUsable, itemID = getterFunc(questLogIndex, questID);
  758. if itemName and itemTexture then
  759. self.itemID = itemID;
  760. self.spellID = nil;
  761. self:Show();
  762. EmbeddedItemTooltip_PrepareForItem(self);
  763. self.Tooltip:SetOwner(self, "ANCHOR_NONE");
  764. self.Tooltip:SetQuestLogItem(rewardType, questLogIndex, questID);
  765. SetItemButtonQuality(self, quality, itemID);
  766. SetItemButtonCount(self, quantity);
  767. self.Icon:SetTexture(itemTexture);
  768. self.itemTextureSet = (itemTexture ~= nil);
  769. self.Tooltip:SetPoint("TOPLEFT", self.Icon, "TOPRIGHT", 0, 10);
  770. EmbeddedItemTooltip_UpdateSize(self);
  771. return true;
  772. end
  773. return false;
  774. end
  775. function EmbeddedItemTooltip_SetSpellByQuestReward(self, rewardIndex, questID)
  776. local texture, name, isTradeskillSpell, isSpellLearned, hideSpellLearnText, isBoostSpell, garrFollowerID, genericUnlock, spellID = GetQuestLogRewardSpell(rewardIndex, questID);
  777. if garrFollowerID then
  778. self:Show();
  779. EmbeddedItemTooltip_PrepareForFollower(self);
  780. local data = GarrisonFollowerTooltipTemplate_BuildDefaultDataForID(garrFollowerID);
  781. GarrisonFollowerTooltipTemplate_SetGarrisonFollower(self.FollowerTooltip, data);
  782. EmbeddedItemTooltip_UpdateSize(self);
  783. return true;
  784. elseif name and texture then
  785. self.itemID = nil;
  786. self.spellID = spellID;
  787. self:Show();
  788. EmbeddedItemTooltip_PrepareForSpell(self);
  789. self.Tooltip:SetOwner(self, "ANCHOR_NONE");
  790. self.Tooltip:SetQuestLogRewardSpell(rewardIndex, questID);
  791. SetItemButtonQuality(self, Enum.ItemQuality.Common);
  792. SetItemButtonCount(self, 0);
  793. self.Icon:SetTexture(texture);
  794. self.Tooltip:SetPoint("TOPLEFT", self.Icon, "TOPRIGHT", 0, 10);
  795. EmbeddedItemTooltip_UpdateSize(self);
  796. return true;
  797. end
  798. return false;
  799. end
  800. function EmbeddedItemTooltip_SetSpellWithTextureByID(self, spellID, texture)
  801. if texture then
  802. self.itemID = nil;
  803. self.spellID = spellID;
  804. self:Show();
  805. EmbeddedItemTooltip_PrepareForSpell(self);
  806. self.Tooltip:SetOwner(self, "ANCHOR_NONE");
  807. self.Tooltip:AddSpellByID(spellID);
  808. SetItemButtonQuality(self, Enum.ItemQuality.Common);
  809. SetItemButtonCount(self, 0);
  810. self.Icon:SetTexture(texture);
  811. self.Tooltip:SetPoint("TOPLEFT", self.Icon, "TOPRIGHT", 0, 10);
  812. EmbeddedItemTooltip_UpdateSize(self);
  813. return true;
  814. end
  815. return false;
  816. end
  817. function EmbeddedItemTooltip_SetCurrencyByID(self, currencyID, quantity)
  818. local currencyInfo = C_CurrencyInfo.GetCurrencyInfo(currencyID);
  819. local name = currencyInfo.name;
  820. local texture = currencyInfo.iconFileID;
  821. local quality = currencyInfo.quality;
  822. if name and texture then
  823. self.itemID = nil;
  824. self.spellID = nil;
  825. self.itemTextureSet = false;
  826. EmbeddedItemTooltip_PrepareForItem(self);
  827. self.Tooltip:SetOwner(self, "ANCHOR_NONE");
  828. self.Tooltip:SetPoint("TOPLEFT", self.Icon, "TOPRIGHT", 0, 10);
  829. local displayQuantity;
  830. name, texture, displayQuantity, quality = CurrencyContainerUtil.GetCurrencyContainerInfo(currencyID, quantity, name, texture, quality);
  831. self.Tooltip:SetCurrencyByID(currencyID, quantity);
  832. SetItemButtonQuality(self, quality, currencyID);
  833. self.Icon:SetTexture(texture);
  834. SetItemButtonCount(self, displayQuantity);
  835. self:Show();
  836. EmbeddedItemTooltip_UpdateSize(self);
  837. return true;
  838. end
  839. return false;
  840. end