UIPanelTemplates.lua

UIPanelTemplates.lua (9.0.1.36272; unchanged since 9.0.1.36230)
  1. ITEM_SEARCHBAR_LIST = {
  2. "BagItemSearchBox",
  3. "GuildItemSearchBox",
  4. "VoidItemSearchBox",
  5. "BankItemSearchBox",
  6. };
  7. function BagSearch_OnHide(self)
  8. local allClosed = true;
  9. for _,barName in pairs(ITEM_SEARCHBAR_LIST) do
  10. local bar = _G[barName];
  11. if bar and bar ~= self and bar:IsVisible() then
  12. allClosed = false;
  13. end
  14. end
  15. if ( allClosed ) then
  16. self.clearButton:Click();
  17. BagSearch_OnTextChanged(self);
  18. end
  19. end
  20. function BagSearch_OnTextChanged(self, userChanged)
  21. SearchBoxTemplate_OnTextChanged(self);
  22. for _, barName in pairs(ITEM_SEARCHBAR_LIST) do
  23. local bar = _G[barName];
  24. if ( bar and bar:GetText() ~= self:GetText() ) then
  25. bar:SetText(self:GetText());
  26. end
  27. end
  28. SetItemSearch(self:GetText());
  29. end
  30. function BagSearch_OnChar(self, text)
  31. -- clear focus if the player is repeating keys (ie - trying to move)
  32. -- TODO: move into base editbox code?
  33. local MIN_REPEAT_CHARACTERS = 4;
  34. local searchString = self:GetText();
  35. if (string.len(searchString) >= MIN_REPEAT_CHARACTERS) then
  36. local repeatChar = true;
  37. for i=1, MIN_REPEAT_CHARACTERS - 1, 1 do
  38. if ( string.sub(searchString,(0-i), (0-i)) ~= string.sub(searchString,(-1-i),(-1-i)) ) then
  39. repeatChar = false;
  40. break;
  41. end
  42. end
  43. if ( repeatChar ) then
  44. self:ClearFocus();
  45. end
  46. end
  47. end
  48. local ROLE_COUNT_EVENTS = {
  49. "GROUP_ROSTER_UPDATE",
  50. "PLAYER_ROLES_ASSIGNED",
  51. };
  52. RoleCountMixin = {};
  53. function RoleCountMixin:OnShow()
  54. self:Refresh();
  55. FrameUtil.RegisterFrameForEvents(self, ROLE_COUNT_EVENTS);
  56. end
  57. function RoleCountMixin:OnHide()
  58. FrameUtil.UnregisterFrameForEvents(self, ROLE_COUNT_EVENTS);
  59. end
  60. function RoleCountMixin:OnEvent()
  61. self:Refresh();
  62. end
  63. function RoleCountMixin:Refresh()
  64. local counts = GetGroupMemberCountsForDisplay();
  65. self.DamagerCount:SetText(counts.DAMAGER);
  66. self.HealerCount:SetText(counts.HEALER);
  67. self.TankCount:SetText(counts.TANK);
  68. end
  69. UIFrameCache = CreateFrame("FRAME");
  70. local caches = {};
  71. function UIFrameCache:New (frameType, baseName, parent, template)
  72. if ( self ~= UIFrameCache ) then
  73. error("Attempt to run factory method on class member");
  74. end
  75. local frameCache = {};
  76. setmetatable(frameCache, self);
  77. self.__index = self;
  78. frameCache.frameType = frameType;
  79. frameCache.baseName = baseName;
  80. frameCache.parent = parent;
  81. frameCache.template = template;
  82. frameCache.frames = {};
  83. frameCache.usedFrames = {};
  84. frameCache.numFrames = 0;
  85. tinsert(caches, frameCache);
  86. return frameCache;
  87. end
  88. function UIFrameCache:GetFrame ()
  89. local frame = self.frames[1];
  90. if ( frame ) then
  91. tremove(self.frames, 1);
  92. tinsert(self.usedFrames, frame);
  93. return frame;
  94. end
  95. frame = CreateFrame(self.frameType, self.baseName .. self.numFrames + 1, self.parent, self.template);
  96. frame.frameCache = self;
  97. self.numFrames = self.numFrames + 1;
  98. tinsert(self.usedFrames, frame);
  99. return frame;
  100. end
  101. function UIFrameCache:ReleaseFrame (frame)
  102. for k, v in next, self.frames do
  103. if ( v == frame ) then
  104. return;
  105. end
  106. end
  107. for k, v in next, self.usedFrames do
  108. if ( v == frame ) then
  109. tinsert(self.frames, frame);
  110. tremove(self.usedFrames, k);
  111. break;
  112. end
  113. end
  114. end
  115. -- SquareButton template code
  116. SQUARE_BUTTON_TEXCOORDS = {
  117. ["UP"] = { 0.45312500, 0.64062500, 0.01562500, 0.20312500};
  118. ["DOWN"] = { 0.45312500, 0.64062500, 0.20312500, 0.01562500};
  119. ["LEFT"] = { 0.23437500, 0.42187500, 0.01562500, 0.20312500};
  120. ["RIGHT"] = { 0.42187500, 0.23437500, 0.01562500, 0.20312500};
  121. ["DELETE"] = { 0.01562500, 0.20312500, 0.01562500, 0.20312500};
  122. };
  123. function SquareButton_SetIcon(self, name)
  124. local coords = SQUARE_BUTTON_TEXCOORDS[strupper(name)];
  125. if (coords) then
  126. self.icon:SetTexCoord(coords[1], coords[2], coords[3], coords[4]);
  127. end
  128. end
  129. -- Cap progress bar
  130. function CapProgressBar_SetNotches(capBar, count)
  131. local barWidth = capBar:GetWidth();
  132. local barName = capBar:GetName();
  133. if ( capBar.notchCount and capBar.notchCount > count ) then
  134. for i = count + 1, capBar.notchCount do
  135. _G[barName.."Divider"..i]:Hide();
  136. end
  137. end
  138. local notchWidth = barWidth / count;
  139. for i=1, count - 1 do
  140. local notch = _G[barName.."Divider"..i];
  141. if ( not notch ) then
  142. notch = capBar:CreateTexture(barName.."Divider"..i, "BORDER", "CapProgressBarDividerTemplate", -1);
  143. end
  144. notch:ClearAllPoints();
  145. notch:SetPoint("LEFT", capBar, "LEFT", notchWidth * i - 2, 0);
  146. end
  147. capBar.notchCount = count;
  148. end
  149. function CapProgressBar_Update(capBar, cap1Quantity, cap1Limit, cap2Quantity, cap2Limit, totalQuantity, totalLimit, hasNoSharedStats)
  150. if ( totalLimit == 0) then
  151. return;
  152. end
  153. local barWidth = capBar:GetWidth() - 4;
  154. local sizePerPoint = barWidth / totalLimit;
  155. local progressWidth = totalQuantity * sizePerPoint;
  156. local cap1Width, cap2Width;
  157. if ( cap2Quantity and cap2Limit ) then
  158. cap1Width = min(cap1Limit - cap1Quantity, cap2Limit - cap2Quantity) * sizePerPoint; --cap1 can't go past the cap2 LFG limit either.
  159. cap2Width = (cap2Limit - cap2Quantity) * sizePerPoint - cap1Width;
  160. else
  161. cap1Width = (cap1Limit - cap1Quantity) * sizePerPoint;
  162. cap2Width = 0;
  163. end
  164. --Don't let it go past the end.
  165. progressWidth = min(progressWidth, barWidth);
  166. cap1Width = min(cap1Width, barWidth - progressWidth);
  167. cap2Width = min(cap2Width, barWidth - progressWidth - cap1Width);
  168. capBar.progress:SetWidth(progressWidth);
  169. capBar.cap1:SetWidth(cap1Width);
  170. capBar.cap2:SetWidth(cap2Width);
  171. local lastFrame, lastRelativePoint = capBar, "LEFT";
  172. if ( progressWidth > 0 ) then
  173. capBar.progress:Show();
  174. capBar.progress:SetPoint("LEFT", lastFrame, lastRelativePoint, 2, 0);
  175. lastFrame, lastRelativePoint = capBar.progress, "RIGHT";
  176. else
  177. capBar.progress:Hide();
  178. end
  179. if ( cap1Width > 0 and not hasNoSharedStats) then
  180. capBar.cap1:Show();
  181. capBar.cap1Marker:Show();
  182. capBar.cap1:SetPoint("LEFT", lastFrame, lastRelativePoint, 0, 0);
  183. lastFrame, lastRelativePoint = capBar.cap1, "RIGHT";
  184. else
  185. capBar.cap1:Hide();
  186. capBar.cap1Marker:Hide();
  187. end
  188. if ( cap2Width > 0 and not hasNoSharedStats) then
  189. capBar.cap2:Show();
  190. capBar.cap2Marker:Show();
  191. capBar.cap2:SetPoint("LEFT", lastFrame, lastRelativePoint, 0, 0);
  192. lastFrame, lastRelativePoint = capBar.cap2, "RIGHT";
  193. else
  194. capBar.cap2:Hide();
  195. capBar.cap2Marker:Hide();
  196. end
  197. end
  198. --Radio button functions
  199. function SetCheckButtonIsRadio(button, isRadio)
  200. if ( isRadio ) then
  201. button:SetNormalTexture("Interface\\Buttons\\UI-RadioButton");
  202. button:GetNormalTexture():SetTexCoord(0, 0.25, 0, 1);
  203. button:SetHighlightTexture("Interface\\Buttons\\UI-RadioButton");
  204. button:GetHighlightTexture():SetTexCoord(0.5, 0.75, 0, 1);
  205. button:SetCheckedTexture("Interface\\Buttons\\UI-RadioButton");
  206. button:GetCheckedTexture():SetTexCoord(0.25, 0.5, 0, 1);
  207. button:SetPushedTexture("Interface\\Buttons\\UI-RadioButton");
  208. button:GetPushedTexture():SetTexCoord(0, 0.25, 0, 1);
  209. button:SetDisabledCheckedTexture("Interface\\Buttons\\UI-RadioButton");
  210. button:GetDisabledCheckedTexture():SetTexCoord(0.75, 1, 0, 1);
  211. else
  212. button:SetNormalTexture("Interface\\Buttons\\UI-CheckBox-Up");
  213. button:GetNormalTexture():SetTexCoord(0, 1, 0, 1);
  214. button:SetHighlightTexture("Interface\\Buttons\\UI-CheckBox-Highlight");
  215. button:GetHighlightTexture():SetTexCoord(0, 1, 0, 1);
  216. button:SetCheckedTexture("Interface\\Buttons\\UI-CheckBox-Check");
  217. button:GetCheckedTexture():SetTexCoord(0, 1, 0, 1);
  218. button:SetPushedTexture("Interface\\Buttons\\UI-CheckBox-Down");
  219. button:GetPushedTexture():SetTexCoord(0, 1, 0, 1);
  220. button:SetDisabledCheckedTexture("Interface\\Buttons\\UI-CheckBox-Check-Disabled");
  221. button:GetDisabledCheckedTexture():SetTexCoord(0, 1, 0, 1);
  222. end
  223. end
  224. --Inline hyperlinks
  225. function InlineHyperlinkFrame_OnEnter(self, link, text, fontString, left, bottom, width, height)
  226. self.tooltipFrame:SetOwner(self, "ANCHOR_PRESERVE");
  227. self.tooltipFrame:ClearAllPoints();
  228. self.tooltipFrame:SetPoint("BOTTOMLEFT", fontString, "TOPLEFT", left + width, bottom);
  229. self.tooltipFrame:SetHyperlink(link);
  230. end
  231. function InlineHyperlinkFrame_OnLeave(self)
  232. self.tooltipFrame:Hide();
  233. end
  234. function InlineHyperlinkFrame_OnClick(self, link, text, button)
  235. if ( self.hasIconHyperlinks ) then
  236. local fixedLink;
  237. local _, _, linkType, linkID = string.find(link, "([%a]+):([%d]+)");
  238. if ( linkType == "currency" ) then
  239. fixedLink = C_CurrencyInfo.GetCurrencyLink(linkID);
  240. end
  241. if ( fixedLink ) then
  242. HandleModifiedItemClick(fixedLink);
  243. return;
  244. end
  245. end
  246. SetItemRef(link, text, button);
  247. end
  248. CurrencyTemplateMixin = {};
  249. function CurrencyTemplateMixin:SetCurrencyFromID(currencyID, amount, formatString, colorCode)
  250. local currencyString = GetCurrencyString(currencyID, amount, colorCode, self.abbreviate);
  251. if formatString then
  252. self:SetText(formatString:format(currencyString));
  253. else
  254. self:SetText(currencyString);
  255. end
  256. self.currencyID = currencyID;
  257. self.amount = amount;
  258. self.formatString = formatString;
  259. self.colorCode = colorCode;
  260. end
  261. function CurrencyTemplateMixin:SetTooltipAnchor(tooltipAnchor)
  262. self.tooltipAnchor = tooltipAnchor;
  263. end
  264. function CurrencyTemplateMixin:SetAbbreviate(abbreviate)
  265. self.abbreviate = abbreviate;
  266. end
  267. function CurrencyTemplateMixin:Refresh()
  268. -- without an override amount this currency is eligible for a refresh
  269. if not self.amount then
  270. local overrideAmount = nil;
  271. self:SetCurrencyFromID(self.currencyID, overrideAmount, self.formatString, self.colorCode);
  272. end
  273. end
  274. function CurrencyTemplateMixin:OnEnter()
  275. if self.tooltipAnchor and self.currencyID then
  276. self:SetScript("OnUpdate", self.OnUpdate);
  277. end
  278. end
  279. function CurrencyTemplateMixin:OnLeave()
  280. self:SetScript("OnUpdate", nil);
  281. GameTooltip:Hide();
  282. end
  283. function CurrencyTemplateMixin:OnUpdate()
  284. if self.Text:IsMouseOver() then
  285. GameTooltip:SetOwner(self, self.tooltipAnchor);
  286. GameTooltip:SetCurrencyByID(self.currencyID);
  287. elseif GameTooltip:GetOwner() == self then
  288. GameTooltip:Hide();
  289. end
  290. end
  291. UIExpandingButtonMixin = {};
  292. function UIExpandingButtonMixin:SetUp(expanded, expansionDirection)
  293. self.expansionDirection = expansionDirection;
  294. self.currentlyExpanded = expanded;
  295. self:Update();
  296. end
  297. function UIExpandingButtonMixin:SetLabel(label)
  298. self.Label:SetText(label);
  299. end
  300. local function GetOppositeDirection(direction)
  301. if (direction == "RIGHT") then
  302. return "LEFT";
  303. else
  304. return "RIGHT";
  305. end
  306. end
  307. function UIExpandingButtonMixin:SetExpanded(expanded)
  308. self.currentlyExpanded = expanded;
  309. self:Update();
  310. end
  311. function UIExpandingButtonMixin:IsCurrentlyExpanded()
  312. return self.currentlyExpanded;
  313. end
  314. function UIExpandingButtonMixin:Update(override)
  315. if (self.currentlyExpanded == nil or not self.expansionDirection) then
  316. error("The button must be set up before update.");
  317. return;
  318. end
  319. if (override ~= nil) then
  320. self.currentlyExpanded = override;
  321. end
  322. local direction = self.currentlyExpanded and GetOppositeDirection(self.expansionDirection) or self.expansionDirection;
  323. SquareButton_SetIcon(self, direction);
  324. if (self.callback) then
  325. self.callback(self, self.currentlyExpanded);
  326. end
  327. end
  328. function UIExpandingButtonMixin:RegisterCallback(callback)
  329. self.callback = callback;
  330. end
  331. function UIExpandingButtonMixin:OnClick(button, down)
  332. self.currentlyExpanded = not self.currentlyExpanded;
  333. self:Update();
  334. end
  335. TalentRankDisplayMixin = { };
  336. function TalentRankDisplayMixin:SetValues(currentRank, maxRank, isDisabled, isAvailable)
  337. self.Text:SetFormattedText(GENERIC_FRACTION_STRING, currentRank, maxRank);
  338. local atlas, textColor;
  339. if isDisabled then
  340. atlas = "orderhalltalents-rankborder";
  341. textColor = DISABLED_FONT_COLOR;
  342. elseif isAvailable and currentRank < maxRank then
  343. atlas = "orderhalltalents-rankborder-green";
  344. textColor = GREEN_FONT_COLOR;
  345. else
  346. atlas = "orderhalltalents-rankborder-yellow";
  347. textColor = YELLOW_FONT_COLOR;
  348. end
  349. local useAtlasSize = true;
  350. self.Background:SetAtlas(atlas, true);
  351. self.Text:SetTextColor(textColor:GetRGB());
  352. end
  353. ButtonWithDisableMixin = {};
  354. function ButtonWithDisableMixin:SetDisableTooltip(tooltipTitle, tooltipText)
  355. self.disableTooltipTitle = tooltipTitle;
  356. self.disableTooltipText = tooltipText;
  357. self:SetEnabled(tooltipTitle == nil);
  358. end
  359. function ButtonWithDisableMixin:OnEnter()
  360. if self.disableTooltipTitle and not self:IsEnabled() then
  361. GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
  362. local wrap = true;
  363. GameTooltip_SetTitle(GameTooltip, self.disableTooltipTitle, RED_FONT_COLOR, wrap);
  364. if self.disableTooltipText then
  365. GameTooltip_AddNormalLine(GameTooltip, self.disableTooltipText, wrap);
  366. end
  367. GameTooltip:Show();
  368. end
  369. end
  370. CurrencyDisplayMixin = CreateFromMixins(CurrencyTemplateMixin);
  371. -- currencies: An array of currencyInfo
  372. -- currencyInfo: either a currencyID, or an array with { currencyID, overrideAmount, colorCode }, or a table with { currencyID = 123, amount = 45 }
  373. function CurrencyDisplayMixin:SetCurrencies(currencies, formatString)
  374. if #currencies == 1 then
  375. local currency = currencies[1];
  376. if type(currency) == "table" then
  377. if currency.currencyID and currency.amount then
  378. self:SetCurrencyFromID(currency.currencyID, currency.amount, formatString);
  379. else
  380. local currencyID, overrideAmount, colorCode = unpack(currency);
  381. self:SetCurrencyFromID(currencyID, overrideAmount, formatString, colorCode);
  382. end
  383. else
  384. self:SetCurrencyFromID(currency);
  385. end
  386. return;
  387. end
  388. local text = GetCurrenciesString(currencies);
  389. if formatString then
  390. self:SetText(formatString:format(text));
  391. else
  392. self:SetText(text);
  393. end
  394. end
  395. function CurrencyDisplayMixin:SetText(text)
  396. self.Text:SetText(text);
  397. end
  398. function CurrencyDisplayMixin:SetTextAnchorPoint(anchorPoint)
  399. self.Text:ClearAllPoints();
  400. self.Text:SetPoint(anchorPoint);
  401. end
  402. CurrencyDisplayGroupMixin = {};
  403. function CurrencyDisplayGroupMixin:OnLoad()
  404. self.currencyFramePool = CreateFramePool("FRAME", self, "CurrencyDisplayTemplate");
  405. end
  406. -- Defaults to a TOPRIGHT configuration.
  407. function CurrencyDisplayGroupMixin:SetCurrencies(currencies, initFunction, initialAnchor, gridLayout, tooltipAnchor, abbreviate, reverseOrder)
  408. self.currencyFramePool:ReleaseAll();
  409. local function FactoryFunction(index)
  410. local currencyFrame = self.currencyFramePool:Acquire();
  411. local tIndex = index;
  412. if reverseOrder then
  413. tIndex = #currencies + 1 - index;
  414. end
  415. local currencyInfo = currencies[tIndex];
  416. currencyFrame:SetTooltipAnchor(tooltipAnchor);
  417. currencyFrame:SetAbbreviate(abbreviate);
  418. if type(currency) == "table" then
  419. currencyFrame:SetCurrencyFromID(unpack(currencyInfo));
  420. else
  421. currencyFrame:SetCurrencyFromID(currencyInfo);
  422. end
  423. if initFunction then
  424. initFunction(currencyFrame);
  425. end
  426. currencyFrame:Show();
  427. return currencyFrame;
  428. end
  429. local initialAnchor = initialAnchor or AnchorUtil.CreateAnchor("TOPRIGHT", self, "TOPRIGHT");
  430. local layout = gridLayout or AnchorUtil.CreateGridLayout(GridLayoutMixin.Direction.TopRightToBottomLeft);
  431. AnchorUtil.GridLayoutFactoryByCount(FactoryFunction, #currencies, initialAnchor, layout);
  432. self:MarkDirty();
  433. end
  434. function CurrencyDisplayGroupMixin:Refresh()
  435. for currencyFrame in self.currencyFramePool:EnumerateActive() do
  436. currencyFrame:Refresh();
  437. end
  438. end
  439. CurrencyHorizontalLayoutFrameMixin = { };
  440. function CurrencyHorizontalLayoutFrameMixin:Clear()
  441. if self.quantityPool then
  442. self.quantityPool:ReleaseAll();
  443. end
  444. if self.iconPool then
  445. self.iconPool:ReleaseAll();
  446. end
  447. self.nextLayoutIndex = nil;
  448. end
  449. function CurrencyHorizontalLayoutFrameMixin:AddToLayout(region)
  450. if not self.nextLayoutIndex then
  451. self.nextLayoutIndex = 1;
  452. end
  453. region.layoutIndex = self.nextLayoutIndex;
  454. self.nextLayoutIndex = self.nextLayoutIndex + 1;
  455. region:Show();
  456. end
  457. function CurrencyHorizontalLayoutFrameMixin:GetQuantityFontString()
  458. if not self.quantityPool then
  459. self.quantityPool = CreateFontStringPool(self, "ARTWORK", 0, (self.quantityFontObject or "GameFontHighlight"));
  460. end
  461. local fontString = self.quantityPool:Acquire();
  462. self:AddToLayout(fontString);
  463. return fontString;
  464. end
  465. function CurrencyHorizontalLayoutFrameMixin:GetIconFrame()
  466. if not self.iconPool then
  467. self.iconPool = CreateFramePool("FRAME", self, "CurrencyLayoutFrameIconTemplate");
  468. end
  469. local frame = self.iconPool:Acquire();
  470. self:AddToLayout(frame);
  471. return frame;
  472. end
  473. function CurrencyHorizontalLayoutFrameMixin:CreateLabel(text, color, fontObject, spacing)
  474. if self.Label then
  475. return;
  476. end
  477. local label = self:CreateFontString(nil, "ARTWORK", fontObject or "GameFontHighlight");
  478. self.Label = label;
  479. label.layoutIndex = 0;
  480. label.rightPadding = spacing;
  481. label:SetHeight(self.fixedHeight);
  482. label:SetText(text);
  483. color = color or HIGHLIGHT_FONT_COLOR;
  484. label:SetTextColor(color:GetRGB());
  485. end
  486. function CurrencyHorizontalLayoutFrameMixin:AddCurrency(currencyID, overrideAmount, color)
  487. local currencyInfo = C_CurrencyInfo.GetCurrencyInfo(currencyID);
  488. if currencyInfo then
  489. local height = self.fixedHeight;
  490. -- quantity
  491. local fontString = self:GetQuantityFontString();
  492. fontString:SetHeight(height);
  493. local amountString = BreakUpLargeNumbers(overrideAmount or currencyInfo.quantity);
  494. fontString:SetText(amountString);
  495. color = color or HIGHLIGHT_FONT_COLOR;
  496. fontString:SetTextColor(color:GetRGB());
  497. -- icon
  498. local frame = self:GetIconFrame();
  499. frame:SetSize(height, height);
  500. frame.Icon:SetTexture(currencyInfo.iconFileID);
  501. frame.id = currencyID;
  502. -- spacing
  503. fontString.rightPadding = self.quantitySpacing;
  504. if fontString.layoutIndex > 1 then
  505. fontString.leftPadding = self.currencySpacing;
  506. end
  507. end
  508. end