k1ck3r

Widgets.lua

Oct 26th, 2021
1,037
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. local Factory, AN, T = {}, ...
  2. local C, EV, L, U, S = C_Garrison, T.Evie, T.L, T.Util, {}
  3. local PROGRESS_MIN_STEP = 0.2
  4. local CovenKit = "NightFae"
  5. local tooltipSharedPB, tooltipShopWatch
  6. local UIBUTTON_HEIGHT = ({zhCN=24, zhTW=24, koKR=24})[GetLocale()] or 22
  7.  
  8. local CreateObject do
  9.     local skip, peekO = {SharedTooltipProgressBar=1, ObjectGroup=1, TexSlice=1, CommonHoverTooltip=1, Shadow=1}
  10.     local function peek(k)
  11.         local o = peekO and peekO[k]
  12.         return o and o.GetObjectType and o or nil
  13.     end
  14.     local function ret(otype, ...)
  15.         local a = ...
  16.         local s, nf = S[a], VPEX_OnUIObjectCreated
  17.         if a and not skip[otype] and type(nf) == "function" and (s or type(a) == "table") then
  18.             local ar = a and a.GetObjectType and a or s and s.GetObjectType and s
  19.             if ar then
  20.                 peekO = s and (ar == s and a or s) or nil
  21.                 securecall(nf, otype, ar, peek)
  22.                 peekO = nil
  23.             end
  24.         end
  25.         return ...
  26.     end
  27.     function CreateObject(otype, ...)
  28.         return ret(otype, assert(Factory[otype], otype)(...))
  29.     end
  30. end
  31. T.Shadows, T.CreateObject = S, CreateObject
  32.  
  33. local function Mirror(tex, swapH, swapV)
  34.     local ulX, ulY, llX, llY, urX, urY, lrX, lrY = tex:GetTexCoord()
  35.     if swapH then
  36.         ulX, ulY, llX, llY, urX, urY, lrX, lrY = urX, urY, lrX, lrY, ulX, ulY, llX, llY
  37.     end
  38.     if swapV then
  39.         ulX, ulY, llX, llY, urX, urY, lrX, lrY = llX, llY, ulX, ulY, lrX, lrY, urX, urY
  40.     end
  41.     tex:SetTexCoord(ulX, ulY, llX, llY, urX, urY, lrX, lrY)
  42.     return tex
  43. end
  44. local function AugmentFollowerInfo(info)
  45.     info.autoCombatantStats = C_Garrison.GetFollowerAutoCombatStats(info.followerID)
  46.     info.autoCombatSpells = C_Garrison.GetFollowerAutoCombatSpells(info.followerID, info.level)
  47.     info.missionTimeEnd = info.missionTimeEnd or info.status == GARRISON_FOLLOWER_ON_MISSION and
  48.         (GetTime() + (C_Garrison.GetFollowerMissionTimeLeftSeconds(info.followerID) or 1)) or nil
  49.     return info
  50. end
  51.  
  52. local GetTimeStringFromSeconds = U.GetTimeStringFromSeconds
  53. local function HideOwnGameTooltip(self)
  54.     if GameTooltip:IsOwned(self) then
  55.         GameTooltip:Hide()
  56.     end
  57. end
  58. local function CommonTooltip_ShopWatch()
  59.     if not tooltipShopWatch or GameTooltip:IsForbidden() or GameTooltip:GetOwner() ~= tooltipShopWatch then
  60.         tooltipShopWatch = nil
  61.         return "remove"
  62.     end
  63.     if IsModifiedClick("COMPAREITEMS") or GetCVarBool("alwaysCompareItems") then
  64.         GameTooltip_ShowCompareItem(GameTooltip, GameTooltip)
  65.     else
  66.         GameTooltip_HideShoppingTooltips(GameTooltip)
  67.     end
  68. end
  69. local function CommonTooltip_ArmShopWatch(self, item)
  70.     if IsEquippableItem(item) and tooltipShopWatch ~= self then
  71.         if not tooltipShopWatch then
  72.             EV.MODIFIER_STATE_CHANGED = CommonTooltip_ShopWatch
  73.         end
  74.         tooltipShopWatch = self
  75.     end
  76. end
  77. local function CommonTooltip_OnEnter(self)
  78.     local showCurrencyBar = false
  79.     if self.tooltipAnchor == "ANCHOR_TRUE_LEFT" then
  80.         GameTooltip:SetOwner(self, "ANCHOR_NONE")
  81.         GameTooltip:SetPoint("RIGHT", self, "LEFT", self.tooltipXO or 0, self.tooltipYO or 0)
  82.     else
  83.         GameTooltip:SetOwner(self, self.tooltipAnchor or "ANCHOR_TOP", self.tooltipXO or 0, self.tooltipYO or 0)
  84.     end
  85.     tooltipShopWatch = not not tooltipShopWatch
  86.     if type(self.mechanicInfo) == "table" then
  87.         local ic, m = self.Icon and self.Icon:GetTexture(), self.mechanicInfo
  88.         ic = ic or m.icon
  89.         GameTooltip:SetText((ic and "|T" .. ic .. ":0:0:0:0:64:64:4:60:4:60|t " or "") .. m.name)
  90.         if (m.enemy or "") ~= "" then
  91.             GameTooltip:AddLine("|cff49C8F2" .. m.enemy)
  92.         elseif (m.description or "") ~= "" then
  93.             GameTooltip:AddLine(m.description, 1,1,1,1)
  94.         end
  95.         if type(m.ability) == "table" then
  96.             local a = m.ability
  97.             GameTooltip:AddLine(" ")
  98.             GameTooltip:AddLine((a.icon and "|T" .. a.icon .. ":0|t " or "") .. a.name)
  99.             if (a.description or "") ~= "" then
  100.                 GameTooltip:AddLine(a.description, 1,1,1,1)
  101.             end
  102.         end
  103.     elseif self.itemLink then
  104.         GameTooltip:SetHyperlink(self.itemLink)
  105.         CommonTooltip_ArmShopWatch(self, self.itemLink)
  106.     elseif self.itemID then
  107.         GameTooltip:SetItemByID(self.itemID)
  108.         CommonTooltip_ArmShopWatch(self, self.itemID)
  109.     elseif self.tooltipHeader and (self.tooltipText or self.tooltipCountdownTo) then
  110.         GameTooltip:AddLine(self.tooltipHeader)
  111.         if self.tooltipCountdownTo then
  112.             GameTooltip:AddLine(GetTimeStringFromSeconds(self.tooltipCountdownTo - GetTime(), false, false, true), 1,1,1)
  113.         else
  114.             GameTooltip:AddLine(self.tooltipText, 1,1,1, self.tooltipTextNW == nil and 1 or nil)
  115.         end
  116.         showCurrencyBar = not not (self.currencyID)
  117.     elseif self.currencyID then
  118.         GameTooltip:SetCurrencyByID(self.currencyID)
  119.         if self.currencyID == 1889 then
  120.             local ci = C_CurrencyInfo.GetCurrencyInfo(self.currencyID)
  121.             local q = ci and U.GetShiftedCurrencyValue(self.currencyID, ci.quantity) or "??"
  122.             GameTooltip:AddLine("|n" .. (L"Current Progress: %s"):format("|cffffffff" .. q .. "|r"))
  123.             GameTooltip:Show()
  124.         end
  125.     elseif self.achievementID then
  126.         local self, achievementID, highlightAsset = GameTooltip, self.achievementID, self.assetID
  127.         local _, n, _points, c, _, _, _, description, _, _icon, _, _, wasEarnedByMe, _earnedBy =
  128.             GetAchievementInfo(achievementID)
  129.         self:SetText(n)
  130.         if not c or not wasEarnedByMe then
  131.             self:AddLine(ACHIEVEMENT_TOOLTIP_IN_PROGRESS:format(UnitName("player")), 0.1, 0.9, 0.1)
  132.             self:AddLine(" ")
  133.         end
  134.         self:AddLine(description, 1,1,1,1)
  135.         local nc = GetAchievementNumCriteria(achievementID)
  136.         for i=1,nc,2 do
  137.             local n1, _, c1, _, _, _, _, asid = GetAchievementCriteriaInfo(achievementID, i)
  138.             n1 = (asid == highlightAsset and "|cffffea00" or c1 and "|cff20c020" or "|cffa8a8a8") .. n1
  139.             if i == nc then
  140.                 self:AddLine(n1)
  141.             else
  142.                 local n2, _, c2, _, _, _, _, asid = GetAchievementCriteriaInfo(achievementID, i+1)
  143.                 n2 = (asid == highlightAsset and "|cffffea00" or c2 and "|cff20c020" or "|cffa8a8a8") .. n2
  144.                 self:AddDoubleLine(n1, n2)
  145.             end
  146.         end
  147.     else
  148.         GameTooltip:Hide()
  149.         return
  150.     end
  151.     if self.ShowQuantityFromWidgetText and not showCurrencyBar then
  152.         local w = self[self.ShowQuantityFromWidgetText]
  153.         local t = w and w:GetText() or ""
  154.         local c = NORMAL_FONT_COLOR
  155.         if t ~= "" then
  156.             GameTooltip:AddLine((L"Quantity: %s"):format("|cffffffff" .. t), c.r, c.g, c.b)
  157.         end
  158.     end
  159.     GameTooltip:Show()
  160.     if self.tooltipPostShow then
  161.         self.tooltipPostShow(GameTooltip, self)
  162.     end
  163.     if showCurrencyBar then
  164.         local q1, factionID, cur, max, label = self.currencyQ, C_CurrencyInfo.GetFactionGrantedByCurrency(self.currencyID)
  165.         if factionID then
  166.             if C_Reputation.IsFactionParagon(factionID) then
  167.                 label, cur, max = _G["FACTION_STANDING_LABEL8" .. (UnitSex("player") ~= 2 and "_FEMALE" or "")], C_Reputation.GetFactionParagonInfo(factionID)
  168.                 cur = cur % max
  169.             else
  170.                 local _, _, stID, bMin, bMax, bVal  = GetFactionInfoByID(factionID)
  171.                 if stID and bMin then
  172.                     cur, max, label = bVal - bMin, bMax-bMin, _G["FACTION_STANDING_LABEL" .. stID .. (UnitSex("player") ~= 2 and "_FEMALE" or "")]
  173.                 end
  174.             end
  175.         end
  176.         if not (cur and max) then
  177.             return
  178.         end
  179.         label = label .. " - " .. BreakUpLargeNumbers(cur) .. " / " .. BreakUpLargeNumbers(max)
  180.         CreateObject("SharedTooltipProgressBar"):Activate(GameTooltip, cur, max, label, self.isRetrospective and 0 or q1)
  181.     end
  182. end
  183. local function CommonTooltip_DelayedRefresh_OnUpdate(self, elapsed)
  184.     local tl = self.tooltipRefreshDelay - (elapsed or 0)
  185.     if not GameTooltip:IsOwned(self) then
  186.         self:SetScript("OnUpdate", nil)
  187.         self.tooltipRefreshDelay = nil
  188.     elseif tl > 0 then
  189.         self.tooltipRefreshDelay = tl
  190.     else
  191.         self:SetScript("OnUpdate", nil)
  192.         self.tooltipRefreshDelay = nil
  193.         self:GetScript("OnEnter")(self)
  194.     end
  195. end
  196. local function CommonLinkable_OnClick(self)
  197.     if self.itemLink then
  198.         HandleModifiedItemClick(self.itemLink)
  199.     elseif not IsModifiedClick("CHATLINK") then
  200.     elseif self.achievementID then
  201.         ChatEdit_InsertLink(GetAchievementLink(self.achievementID))
  202.     elseif self.itemID then
  203.         local _, link = GetItemInfo(self.itemID)
  204.         if link then
  205.             ChatEdit_InsertLink(link)
  206.         end
  207.     elseif self.currencyID and self.currencyID ~= 0 then
  208.         ChatEdit_InsertLink(C_CurrencyInfo.GetCurrencyLink(self.currencyID, self.currencyAmount or 0))
  209.     end
  210. end
  211. local function MissionList_ScrollToward(self, obj)
  212.     if obj:GetBottom() < self:GetBottom() then
  213.         self:GetScript("OnMouseWheel")(self, -1)
  214.     elseif obj:GetTop() > self:GetTop() then
  215.         self:GetScript("OnMouseWheel")(self, 1)
  216.     end
  217. end
  218. local function MissionList_SpawnMissionButton(arr, i)
  219.     local prev = type(i) == "number" and rawget(arr, i-1)
  220.     if type(prev) == "table" then
  221.         local cf = CreateObject("MissionButton", prev:GetParent())
  222.         arr[i] = cf
  223.         cf:SetPoint("TOPLEFT", 292*(((i-1)%3)+1)-284, math.floor((i-1)/3) *- 195)
  224.         return cf
  225.     end
  226. end
  227. local function MissionButton_OnClick(self)
  228.     local s = S[self]
  229.     if IsModifiedClick("CHATLINK") and s.missionID then
  230.         ChatEdit_InsertLink(C.GetMissionLink(s.missionID))
  231.     else
  232.         self:GetParent():GetParent():ScrollToward(self)
  233.     end
  234. end
  235. local function MissionButton_OnProgressBarClick(self)
  236.     local s = S[self:GetParent()]
  237.     if s.missionID and s.completableAfter and s.completableAfter <= GetTime() then
  238.         U.InitiateMissionCompletion(s.missionID)
  239.     end
  240. end
  241. local function MissionButton_OnViewClick(self)
  242.     U.ShowMission(S[self:GetParent()].missionID, self:GetParent():GetParent():GetParent():GetParent())
  243. end
  244. local function MissionButton_SetGroupPortraits(mb, g, isVeiled, altWidget)
  245.     local hasGroup = g and next(g) ~= nil or false
  246.     mb.Group:SetShown(hasGroup)
  247.     altWidget:SetShown(not hasGroup)
  248.     local s = S[mb.Group]
  249.     local vc = isVeiled and 0.85 or 1
  250.     for i=0, hasGroup and 4 or -1 do
  251.         local f = g[i]
  252.         local t = f and C_Garrison.GetFollowerPortraitIconID(f)
  253.         local c = t and vc or 0.2
  254.         s[i]:SetTexture(t or "Interface/Masks/CircleMask")
  255.         s[i]:SetVertexColor(c, c, c)
  256.         s[5+i]:SetVertexColor(vc, vc, vc)
  257.     end
  258. end
  259. local function Progress_UpdateTimer(self)
  260.     local now, endTime = GetTime(), self.endTime
  261.     if endTime <= now then
  262.         self.Fill:SetWidth(math.max(0.01, self:GetWidth()))
  263.         self.Fill:SetTexCoord(0, 1, 0, 1)
  264.         self:SetScript("OnUpdate", nil)
  265.         if self.endText then
  266.             self.Text:SetText(self.endText)
  267.         end
  268.         self:SetEnabled(not not self.endClick)
  269.         self.endTime, self.duration, self.endText, self.nextUp = nil
  270.     elseif (self.nextUp or now) <= now then
  271.         local w, d = self:GetWidth(), self.duration
  272.         local secsLeft, p = endTime-now-0.5, math.min(1, 1-(endTime-now)/d)
  273.         self.Fill:SetWidth(math.max(0.01, w*p))
  274.         self.Fill:SetTexCoord(0, math.max(1/128, p), 0, 1)
  275.         self.nextUp = now + math.min(PROGRESS_MIN_STEP/w * d, 0.01 + secsLeft % (secsLeft < 100 and 1 or 60))
  276.         if self.showTimeRemaining then
  277.             self.Text:SetText(GetTimeStringFromSeconds(secsLeft, false, true))
  278.         else
  279.             self.Text:SetText("")
  280.         end
  281.         self:Disable()
  282.     end
  283. end
  284. local function Progress_SetProgress(self, progress)
  285.     progress = progress > 1 and 1 or progress
  286.     self.Fill:SetWidth(math.max(0.01,self:GetWidth()*progress))
  287.     self.Fill:SetTexCoord(0, math.max(1/128, progress), 0, 1)
  288.     self.endTime, self.duration, self.endText, self.endClick, self.nextUp = nil
  289.     self:SetScript("OnUpdate", nil)
  290. end
  291. local function Progress_SetTimer(self, endTime, duration, endText, endClick, showTimeRemaining)
  292.     self.endTime, self.duration, self.endText, self.endClick, self.showTimeRemaining, self.nextUp = endTime, duration, endText, endClick == true or nil, showTimeRemaining == true or nil, nil
  293.     self:SetScript("OnUpdate", Progress_UpdateTimer)
  294.     Progress_UpdateTimer(self)
  295. end
  296. local function TooltipProgressBar_Update(self)
  297.     local p = self:GetParent()
  298.     local pt, sb, pw = p:GetTop(), self:GetBottom(), p:GetWidth()
  299.     if pt and sb then
  300.         p:SetHeight(pt-sb+8)
  301.     end
  302.     if pw then
  303.         self:SetWidth(pw - 20)
  304.     end
  305.     self.Bar:SetProgress(self.pv)
  306.     self.Fill2:SetWidth(self.Bar:GetWidth()*self.v2)
  307. end
  308. local function TooltipProgressBar_Activate(self, tip, cur, max, label, q1)
  309.     if not (cur and max) then
  310.         return
  311.     end
  312.     self.pv = cur/max
  313.     self.v2 = math.max(0.00001, math.min(1-self.pv, (q1 or 0)/max))
  314.     self.Bar.Text:SetText(label)
  315.     self.Fill2:SetAtlas((cur+ (q1 or 0)) > max and "UI-Frame-Bar-Fill-Green" or "UI-Frame-Bar-Fill-Yellow")
  316.     local tl = (q1 or 0)/max
  317.     self.Fill2:SetTexCoord(tl, tl+self.v2, 0, 1)
  318.     self.Fill2:SetShown((q1 or 0) > 0)
  319.     self:SetParent(tip)
  320.     tip:AddLine(("|TInterface/Minimap/PartyRaidBlipsV2:5:65:0:0:64:32:62:63:0:2|t "):rep(3))
  321.     local lastLine = _G[tip:GetName() .. "TextLeft" .. (tip:NumLines()-1)]
  322.     self:SetPoint("TOPLEFT", lastLine, "BOTTOMLEFT", 0, -2)
  323.     self:Show()
  324.     tip:Show()
  325.     TooltipProgressBar_Update(self)
  326. end
  327. local function TooltipProgressBar_OnHide(self)
  328.     self:Hide()
  329.     self:SetParent(nil)
  330.     self:ClearAllPoints()
  331. end
  332. local function CountdownText_OnUpdate(self)
  333.     local now = GetTime()
  334.     if now >= self.cdtTick then
  335.         local cdTo = self.cdtTo
  336.         local secsLeft = cdTo-now
  337.         if secsLeft <= 0 then
  338.             self.CDTDisplay:SetText(self.cdtRest)
  339.             self:SetScript("OnUpdate", nil)
  340.             self.cdtTick, self.cdtTo = nil
  341.         else
  342.             self.cdtTick = secsLeft < 120 and (now + secsLeft % 0.5 + 0.01) or (now + secsLeft % 60 + 0.01)
  343.             self.CDTDisplay:SetText(self.cdtPrefix .. GetTimeStringFromSeconds(secsLeft, self.cdtShort, self.cdtRoundedUp) .. self.cdtSuffix .. self.cdtRest)
  344.         end
  345.     end
  346. end
  347. local function CountdownText_SetCountdown(self, prefix, expireAt, suffix, rest, isShort, isRoundUp)
  348.     prefix, suffix, rest = prefix or "", suffix or "", rest or ""
  349.     local now = GetTime()
  350.     if not (expireAt and expireAt > now) then
  351.         self.CDTDisplay:SetText(rest or "")
  352.         self:SetScript("OnUpdate", nil)
  353.     else
  354.         self.cdtTick, self.cdtPrefix, self.cdtTo, self.cdtSuffix, self.cdtRest, self.cdtShort, self.cdtRoundedUp = now, prefix, expireAt, suffix, rest, isShort, isRoundUp == true
  355.         self:SetScript("OnUpdate", CountdownText_OnUpdate)
  356.         CountdownText_OnUpdate(self)
  357.     end
  358. end
  359. local function ResizedButton_SetText(self, text)
  360.     (self.Text or self):SetText(text)
  361.     self:SetWidth((self.Text or self):GetStringWidth()+26)
  362. end
  363. local function ResourceButton_Update(self, _event, currencyID)
  364.     if currencyID == self.currencyID then
  365.         local ci = C_CurrencyInfo.GetCurrencyInfo(currencyID)
  366.         local quant = ci and U.GetShiftedCurrencyValue(currencyID, ci.quantity)
  367.         if quant then
  368.             self.Text:SetText(BreakUpLargeNumbers(quant))
  369.             self:SetWidth(self.Text:GetStringWidth()+26)
  370.         end
  371.         if GameTooltip:IsOwned(self) and GameTooltip:IsShown() then
  372.             self:GetScript("OnEnter")(self)
  373.         end
  374.     end
  375. end
  376. local function ResourceButton_OnClick(self)
  377.     if IsModifiedClick("CHATLINK") then
  378.         ChatEdit_InsertLink(C_CurrencyInfo.GetCurrencyLink(self.currencyID, 42))
  379.     end
  380. end
  381. local function SetRarityBorder(b, r, atlas)
  382.     r = type(r) == "number" and r or 2
  383.     local vc = (atlas or r >= 1) and 1 or 0.65
  384.     b:SetAtlas(atlas
  385.         or r <= 1 and "loottoast-itemborder-gold"
  386.         or r == 2 and "loottoast-itemborder-green"
  387.         or r == 3 and "loottoast-itemborder-blue"
  388.         or r == 4 and "loottoast-itemborder-purple"
  389.         or r == 9 and "loottoast-itemborder-gold"
  390.         or "loottoast-itemborder-orange")
  391.     b:SetDesaturated(r <= 1 and not atlas)
  392.     b:SetVertexColor(vc, vc, vc)
  393. end
  394. local RewardButton_SetReward do
  395.     local baseXPReward = {title=L"Follower XP", tooltip=L"Awarded even if the adventurers are defeated.", icon="Interface/Icons/XP_Icon", qualityAtlas="loottoast-itemborder-purple"}
  396.     function RewardButton_SetReward(self, rew, isOvermax, pw)
  397.         if rew == "xp" then
  398.             baseXPReward.followerXP = isOvermax
  399.             return RewardButton_SetReward(self, baseXPReward)
  400.         end
  401.         self:SetShown(not not rew)
  402.         if not rew then
  403.             return
  404.         end
  405.         local q, tooltipTitle, tooltipText, cq = rew.quantity, rew.title
  406.         if rew.icon then
  407.             self.Icon:SetTexture(rew.icon)
  408.         elseif rew.itemID then
  409.             self.Icon:SetTexture(GetItemIcon(rew.itemID))
  410.         end
  411.         self.RarityBorder:SetDesaturated(false)
  412.         self.RarityBorder:SetVertexColor(1,1,1)
  413.         if rew.currencyID then
  414.             if rew.currencyID == 0 then
  415.                 q = math.floor(rew.quantity / 1e4)
  416.                 tooltipText = GetMoneyString(rew.quantity)
  417.                 SetRarityBorder(self.RarityBorder, 9)
  418.             else
  419.                 local ci = C_CurrencyInfo.GetCurrencyContainerInfo(rew.currencyID, rew.quantity)
  420.                 if ci then
  421.                     self.Icon:SetTexture(ci.icon)
  422.                     tooltipTitle = (ci.quality and "|c" .. (select(4,GetItemQualityColor(ci.quality)) or "ff00ffff") or "") .. ci.name
  423.                     tooltipText = NORMAL_FONT_COLOR_CODE .. (ci.description or "")
  424.                 end
  425.                 local ci2 = C_CurrencyInfo.GetCurrencyInfo(rew.currencyID)
  426.                 SetRarityBorder(self.RarityBorder, ci and ci.quality or ci2 and ci2.quality)
  427.                 cq = (isOvermax and pw and pw.currencyID == rew.currencyID and pw.currencyQ or 0) + q
  428.             end
  429.         elseif rew.itemID then
  430.             q = rew.quantity == 1 and "" or rew.quantity or ""
  431.             local r = select(3,GetItemInfo(rew.itemLink or rew.itemID)) or select(3,GetItemInfo(rew.itemID)) or 2
  432.             SetRarityBorder(self.RarityBorder, r)
  433.         elseif rew.followerXP then
  434.             q, tooltipTitle, tooltipText = BreakUpLargeNumbers(rew.followerXP), rew.title, rew.tooltip
  435.             SetRarityBorder(self.RarityBorder, 2, rew.qualityAtlas)
  436.         end
  437.         self.currencyID, self.currencyAmount, self.currencyQ = rew.currencyID, rew.quantity, cq
  438.         self.itemID, self.itemLink = rew.itemID, rew.itemLink
  439.         self.tooltipHeader, self.tooltipText = tooltipTitle, tooltipText
  440.         self.Quantity:SetText(q == 1 and "" or q or "")
  441.     end
  442. end
  443. local function RewardBlock_SetRewards(self, xp, rw)
  444.     local nc = xp and (self[1]:SetReward("xp", xp) and nil or 2) or 1
  445.     nc = nc + (self[nc]:SetReward(rw and rw[1]) and nil or 1)
  446.     nc = nc + (self[nc]:SetReward(rw and rw[2]) and nil or 1)
  447.     for i=nc, #self do self[i]:SetReward() end
  448.     if self.Container then
  449.         self.Container:SetWidth((self[1]:GetWidth()+4)*((xp and 1 or 0) + (rw and #rw or 0))-2)
  450.     elseif self.Label then
  451.         self[1]:GetParent():SetWidth(self.Label:GetStringWidth()+16+32*(1+(rw and #rw or 0)))
  452.     end
  453. end
  454. local function FollowerButton_OnDragStart(self)
  455.     if self:IsEnabled() then
  456.         local fa = CovenantMissionFrame.MissionTab.MissionPage.Board.framesByBoardIndex
  457.         local fid = self.info.followerID
  458.         if not self.info.isAutoTroop then
  459.             for i=0,4 do
  460.                 local f = fa[i]
  461.                 if f:IsShown() and f:GetFollowerGUID() == fid then
  462.                     return
  463.                 end
  464.             end
  465.         end
  466.         CovenantMissionFrame:OnDragStartFollowerButton(CovenantMissionFrame:GetPlacerFrame(), self, 24);
  467.     end
  468. end
  469. local function FollowerButton_OnDragStop(self)
  470.     if self:IsEnabled() then
  471.         CovenantMissionFrame:OnDragStopFollowerButton(CovenantMissionFrame:GetPlacerFrame());
  472.     end
  473. end
  474. local function GetAltModifierKeyText(ex)
  475.     local m = GetModifiedClick(ex)
  476.     return m and m:match("ALT") and CTRL_KEY_TEXT or ALT_KEY_TEXT
  477. end
  478. local function IsAltModifiedClick(ex)
  479.     local m = GetModifiedClick(ex)
  480.     if m and m:match("ALT") then
  481.         return IsControlKeyDown()
  482.     else
  483.         return IsAltKeyDown()
  484.     end
  485. end
  486. local function FollowerButton_OnClick(self, b)
  487.     if b == "LeftButton" and not self.info.isAutoTroop and IsAltModifiedClick("CHATLINK") then
  488.         local gid = self.info.garrFollowerID
  489.         U.FollowerSetFavorite(gid, not U.FollowerIsFavorite(gid))
  490.         GameTooltip:Hide()
  491.         self:GetParent():Refresh()
  492.         return
  493.     elseif b == "RightButton" then
  494.         local fa = CovenantMissionFrame.MissionTab.MissionPage.Board.framesByBoardIndex
  495.         local fid = self.info.followerID
  496.         for i=0,self.info.isAutoTroop and -1 or 4 do
  497.             if fa[i]:GetFollowerGUID() == fid then
  498.                 CovenantMissionFrame:RemoveFollowerFromMission(fa[i], true)
  499.                 return
  500.             end
  501.         end
  502.         CovenantMissionFrame.MissionTab.MissionPage:AddFollower(fid)
  503.     elseif b == "LeftButton" and IsModifiedClick("CHATLINK") then
  504.         ChatEdit_InsertLink(C.GetFollowerLink(self.info.followerID))
  505.     end
  506.     self:GetParent():SyncToBoard()
  507. end
  508. local function FollowerButton_OnEnter(self)
  509.     local info = self.info
  510.     if not info then return end
  511.     GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
  512.     U.SetFollowerInfo(GameTooltip, info, info.autoCombatSpells, nil, nil, nil, nil, true)
  513.     local tmid = U.FollowerHasTentativeGroup(info.followerID)
  514.     if info.status == GARRISON_FOLLOWER_ON_MISSION and info.missionTimeEnd then
  515.         local tl = math.max(0, info.missionTimeEnd-GetTime())
  516.         GameTooltip:AddLine(" ")
  517.         GameTooltip:AddLine(tl > 0 and COVENANT_MISSIONS_ON_ADVENTURE_DURATION:format(GetTimeStringFromSeconds(tl, false, true, true)) or COVENANT_FOLLOWER_MISSION_COMPLETE, 1, 0.4, 0)
  518.         GameTooltip:Show()
  519.     elseif tmid and C_Garrison.GetMissionTimes(tmid) then
  520.         local tn = C_Garrison.GetMissionName(tmid)
  521.         GameTooltip:AddLine(" ")
  522.         GameTooltip:AddLine((L"In Tentative Party - %s"):format(tn or "??"), 1, 0.4, 0)
  523.         GameTooltip:Show()
  524.     end
  525.     if not (info.isAutoTroop or info.missionTimeEnd) then
  526.         local act = U.FollowerIsFavorite(info.garrFollowerID) and BATTLE_PET_UNFAVORITE or BATTLE_PET_FAVORITE
  527.         local short = GetAltModifierKeyText("CHATLINK") .. "+|TInterface\\TUTORIALFRAME\\UI-TUTORIAL-FRAME:0:0:0:-1:512:512:2:78:240:316|t: "
  528.         GameTooltip:AddLine(" ")
  529.         GameTooltip:AddLine(short .. act, 0.5, 0.8, 1)
  530.         GameTooltip:Show()
  531.     end
  532. end
  533. local function FollowerButton_GetInfo(self)
  534.     return self.info
  535. end
  536. local function FollowerButton_GetFollowerGUID(self)
  537.     return self.info.followerID
  538. end
  539. local function FollowerButton_SetInfo(self, info)
  540.     local s = S[self]
  541.     local onMission = info.status == GARRISON_FOLLOWER_ON_MISSION
  542.     local inTG = not info.isAutoTroop and U.FollowerHasTentativeGroup(info.followerID)
  543.     local vc, dc = inTG and 0.55 or onMission and 0.25 or 1, onMission and 0.65 or 1
  544.     local mc = onMission and DISABLED_FONT_COLOR or NORMAL_FONT_COLOR
  545.     local mtl = info.missionTimeEnd and GetTimeStringFromSeconds(math.max(0, info.missionTimeEnd-GetTime()), 2, true, true) or ""
  546.     self.info = info
  547.     s.Portrait:SetTexture(info.portraitIconID)
  548.     s.Portrait2:SetTexture(info.portraitIconID)
  549.     s.TextLabel:SetText(onMission and mtl or info.level)
  550.     s.TextLabel:SetTextColor(mc.r, mc.g, mc.b)
  551.     s.PortraitR:SetVertexColor(dc, dc, dc)
  552.     s.PortraitT:SetShown(inTG)
  553.     s.Portrait:SetVertexColor(vc, vc, vc)
  554.     s.Portrait2:SetShown(inTG or onMission)
  555.     s.Favorite:SetShown(not info.isAutoTroop and not (onMission and inTG) and (info.soFavorite or 0) > 0)
  556.     if inTG then
  557.         s.Portrait2:SetVertexColor(0.6, 0, 0)
  558.     else
  559.         s.Portrait2:SetVertexColor(1, 1, 1)
  560.     end
  561.     local ir = info.role
  562.     s.Role:SetAtlas(ir == 1 and "adventures-dps" or ir == 4 and "adventures-healer" or ir == 5 and "adventures-tank" or "adventures-dps-ranged")
  563.     self:SetEnabled(not onMission)
  564.     s.Health:SetShown(not onMission)
  565.     local cs = info.autoCombatantStats
  566.     s.Health:SetWidth(s.HealthBG:GetWidth()*math.min(1, cs and (cs.currentHealth/cs.maxHealth)+0.001 or 0.001))
  567.     s.ExtraTex:SetDesaturated(onMission)
  568.     if info.missionTimeEnd then
  569.         local t = GetTime()
  570.         local tl = info.missionTimeEnd-t
  571.         local te = tl > 1 and (t+tl%60+0.05)
  572.         if te and te < (self:GetParent().nextUpdate or 0) then
  573.             self:GetParent().nextUpdate = te
  574.         end
  575.     end
  576.     local ns = info.autoCombatSpells and #info.autoCombatSpells or 0
  577.     for i=1,ns do
  578.         local sp = info.autoCombatSpells[i]
  579.         s.Abilities[i]:SetTexture(sp.icon)
  580.         s.Abilities[i]:Show()
  581.         s.AbilitiesB[i]:Show()
  582.     end
  583.     for i=ns+1, #s.Abilities do
  584.         s.Abilities[i]:Hide()
  585.         s.AbilitiesB[i]:Hide()
  586.     end
  587.     if onMission then
  588.         s.HealthBG:SetGradient("VERTICAL", 0.1,0.1,0.1, 0.2,0.2, 0.2)
  589.     else
  590.         s.HealthBG:SetGradient("VERTICAL", 0.07,0.07,0.07, 0.14,0.14,0.14)
  591.     end
  592. end
  593. local SortFollowerList, CompareFollowerXP do
  594.     local preferLowHealth, uiOrder
  595.     local function FollowerList_Compare(a,b)
  596.         local ac, bc = a.missionTimeEnd, b.missionTimeEnd
  597.         if ac ~= bc then
  598.             if ac and bc then
  599.                 return ac < bc
  600.             else
  601.                 return not ac
  602.             end
  603.         end
  604.         ac, bc = not a.inTentativeGroup, not b.inTentativeGroup
  605.         if ac ~= bc then
  606.             return ac
  607.         end
  608.         local uiFree = uiOrder and not (a.missionTimeEnd or a.inTentativeGroup)
  609.         if uiFree and a.soFavorite ~= b.soFavorite then
  610.             ac, bc = a.soFavorite, b.soFavorite
  611.         else
  612.             ac, bc = a.level, b.level
  613.         end
  614.         if preferLowHealth and ac == bc then
  615.             ac, bc = a.autoCombatantStats, b.autoCombatantStats
  616.             ac, bc = ac and -ac.currentHealth/ac.maxHealth or 0, bc and -bc.currentHealth/bc.maxHealth or 0
  617.         end
  618.         if uiFree and ac == bc then
  619.             ac, bc = #(a.autoCombatSpells or "1"), #(b.autoCombatSpells or "1")
  620.         end
  621.         if ac == bc then
  622.             ac, bc = a.xp, b.xp
  623.         end
  624.         if ac == bc then
  625.             ac, bc = a.autoCombatantStats, b.autoCombatantStats
  626.             ac, bc = ac and ac.maxHealth or 0, bc and bc.maxHealth or 0
  627.         end
  628.         if ac == bc then
  629.             ac, bc = b.name, a.name
  630.         end
  631.         return ac > bc
  632.     end
  633.     function CompareFollowerXP(a,b)
  634.         local ac, bc = a.level, b.level
  635.         if ac == bc then
  636.             ac, bc = a.xp, b.xp
  637.         end
  638.         if ac == bc then
  639.             ac, bc = a.name, b.name
  640.         end
  641.         return ac > bc
  642.     end
  643.     function SortFollowerList(list, preferLowHP, forUI)
  644.         preferLowHealth, uiOrder = preferLowHP, forUI
  645.         for i=1,#list do
  646.             list[i].inTentativeGroup = U.FollowerHasTentativeGroup(list[i].followerID)
  647.             list[i].soFavorite = forUI and U.FollowerIsFavorite(list[i].garrFollowerID) and 1 or 0
  648.         end
  649.         table.sort(list, FollowerList_Compare)
  650.     end
  651. end
  652. local function FollowerList_GetTroopHint(ft)
  653.     local o
  654.     if #ft > 0 then
  655.         table.sort(ft, CompareFollowerXP)
  656.         local m = (#ft + #ft%2)/2
  657.         local ml = ft[m].level
  658.         if #ft % 2 == 0 then
  659.             local fi = ft[m+1]
  660.             o = "|cffa0a0a0[" .. fi.level .. "]|r |cffffffff" .. fi.name .. "|r"
  661.             ml = (ml+fi.level)/2
  662.         end
  663.         for i=ft[m].level == 60 and 0 or m, 1, -1 do
  664.             local fi = ft[i]
  665.             o = "|cffa0a0a0[" .. fi.level .. "]|r |cffffffff" .. fi.name .. "|r" .. (o and "\n" .. o or "")
  666.             if i == 1 or ft[i].level ~= ft[i-1].level then
  667.                 break
  668.             end
  669.         end
  670.         local mlc = ("%s%.3g|r"):format(NORMAL_FONT_COLOR_CODE, ml)
  671.         o = (L"Your troop level is the median level of your companions (%s), rounded down. It does not decrease when you recruit additional companions."):format(mlc)
  672.             .. (ml < 60 and "\n\n" .. NORMAL_FONT_COLOR_CODE .. L"These companions currently affect your troop level:" .. "|r\n" .. o or "")
  673.     end
  674.     return COVENANT_MISSIONS_TUTORIAL_TROOPS .. (o and ("\n\n" .. o) or "")
  675. end
  676. local function FollowerList_SyncToBoard(self)
  677.     local fa = CovenantMissionFrame.MissionTab.MissionPage.Board.framesByBoardIndex
  678.     local ca = S[self].companions
  679.     for i=1, #ca do
  680.         local c = ca[i]
  681.         local isInMission = false
  682.         for i=0, c:IsShown() and 4 or -1 do
  683.             local f = fa[i]
  684.             if f and f.name and f:IsShown() and f.info and f.info.followerID == c.info.followerID then
  685.                 isInMission = true
  686.                 break
  687.             end
  688.         end
  689.         if S[c].EC then
  690.             S[c].EC:SetShown(isInMission)
  691.         end
  692.     end
  693. end
  694. local function FollowerList_SyncXPGain(self, setXPGain)
  695.     local ca = S[self].companions
  696.     local xpGain = type(setXPGain) == "number" and setXPGain or self.xpGain or -1
  697.     self.xpGain = xpGain
  698.     for i=1,#ca do
  699.         local w = ca[i]
  700.         local info = w.info
  701.         local isAway = (info and info.status == GARRISON_FOLLOWER_ON_MISSION)
  702.         local willLevel = (info and not info.isAutoTroop and not info.isMaxLevel and info.xp and info.levelXP and (info.levelXP-info.xp) <= xpGain)
  703.         S[w].Blip:SetShown(willLevel and not isAway)
  704.     end
  705. end
  706. local function FollowerList_Refresh(self, setXPGain)
  707.     local s = S[self]
  708.     local wt, wf = s.troops, s.companions
  709.     if self.noRefresh == nil then
  710.         local fl = C_Garrison.GetFollowers(123)
  711.         local ft = C_Garrison.GetAutoTroops(123)
  712.         for i=1,#ft do
  713.             FollowerButton_SetInfo(wt[i], AugmentFollowerInfo(ft[i]))
  714.         end
  715.         for i=1,#fl do
  716.             AugmentFollowerInfo(fl[i])
  717.         end
  718.         s.TroopInfo.tooltipText = FollowerList_GetTroopHint(fl)
  719.         SortFollowerList(fl, false, true)
  720.         for i=1,#fl do
  721.             local fi = fl[i]
  722.             FollowerButton_SetInfo(wf[i], fi)
  723.             wf[i]:Show()
  724.         end
  725.         for i=#fl+1,#wf do
  726.             wf[i]:Hide()
  727.         end
  728.         self:SetHeight(90+72*math.ceil(#fl/4))
  729.         self.noRefresh = true
  730.     end
  731.     FollowerList_SyncToBoard(self)
  732.     FollowerList_SyncXPGain(self, setXPGain)
  733. end
  734. local function FollowerList_OnUpdate(self)
  735.     local t = GetTime()
  736.     self.noRefresh = nil
  737.     if t >= (self.nextUpdate or 0) then
  738.         self.nextUpdate = t+60
  739.         self:Refresh()
  740.         local mf = GetMouseFocus()
  741.         if mf and mf:GetParent() == self and GameTooltip:IsOwned(mf) then
  742.             local f = mf:GetScript("OnEnter")
  743.             if f then f(mf) end
  744.         end
  745.     end
  746. end
  747. local function DoomRun_OnEnter(self)
  748.     local ft, g, gn = C_Garrison.GetFollowers(123), {}, 0
  749.     SortFollowerList(ft, true, false)
  750.     for i=#ft,1,-1 do
  751.         local fi = ft[i]
  752.         if fi.isCollected and not fi.isMaxLevel and fi.status ~= GARRISON_FOLLOWER_ON_MISSION
  753.            and not U.FollowerHasTentativeGroup(fi.followerID)
  754.            and C_Garrison.GetFollowerAutoCombatStats(fi.followerID).currentHealth > 0 then
  755.             g[gn], gn = i, gn + 1
  756.             if gn == 5 then
  757.                 break
  758.             end
  759.         end
  760.     end
  761.     local xpR = S[self:GetParent()].baseXPReward
  762.     local xpT = "|cff00ff00" .. GARRISON_REWARD_XP_FORMAT:format(BreakUpLargeNumbers(xpR)) .. "|r"
  763.     GameTooltip:SetOwner(self, "ANCHOR_TOP")
  764.     GameTooltip:SetText(L"Doomed Run")
  765.     GameTooltip:AddLine(L("Failing this mission grants %s to each companion."):format(xpT), 1,1,1,1)
  766.     if gn > 0 then
  767.         GameTooltip:AddLine(" ")
  768.         for i=0, gn-1 do
  769.             local fi = ft[g[i]]
  770.             local willLevelUp = fi.levelXP and fi.xp and fi.levelXP - fi.xp <= xpR or false
  771.             local upTex = willLevelUp and " |A:bags-greenarrow:0:0|a" or ""
  772.             GameTooltip:AddLine("|cffa0a0a0[" .. fi.level .. "]|r " .. fi.name .. upTex, 1,1,1)
  773.             g[i] = fi.followerID
  774.         end
  775.         GameTooltip:AddLine(L"Tentatively assign these rookies to this adventure.", 0.2,1,0.2, 1)
  776.         GameTooltip:AddLine("|TInterface/TUTORIALFRAME/UI-TUTORIAL-FRAME:14:12:0:-1:512:512:10:70:330:410|t " .. L"Start the adventure", 0.5, 0.8, 1)
  777.     end
  778.     self.group = gn > 0 and g or nil
  779.     GameTooltip:Show()
  780. end
  781. local function DoomRun_OnClick(self, button)
  782.     local mid = S[self:GetParent()].missionID
  783.     local g, st = self.group, self.showTime
  784.     local inShowCooldown = (GetTime()-st < 0.25)
  785.     if not (mid and g and st) or inShowCooldown then return end
  786.     if GameTooltip:IsOwned(self) then
  787.         GameTooltip:Hide()
  788.     end
  789.     if button == "RightButton" then
  790.         U.StartMissionWithDelay(mid, g)
  791.     else
  792.         U.StoreMissionGroup(mid, g)
  793.         PlaySound(SOUNDKIT.U_CHAT_SCROLL_BUTTON)
  794.     end
  795.     EV("I_MISSION_LIST_UPDATE")
  796. end
  797. local function DoomRun_OnShow(self)
  798.     self.showTime = GetTime()
  799. end
  800. local function TentativeGroupClear_OnClick(self)
  801.     local mid = S[self:GetParent()].missionID
  802.     U.StoreMissionGroup(mid, nil)
  803.     PlaySound(SOUNDKIT.U_CHAT_SCROLL_BUTTON)
  804. end
  805. local function getWastedRewards(r)
  806.     local o
  807.     for i=1, r and #r or 0 do
  808.         local ri = r[i]
  809.         local cid = ri and ri.currencyID
  810.         if cid and cid ~= 0 and ri.quantity then
  811.             local ci = C_CurrencyInfo.GetCurrencyInfo(cid)
  812.             local wq = ci and (ci.maxQuantity or 0) > 0 and ci.quantity and math.min(ci.quantity, ci.quantity + ri.quantity - ci.maxQuantity) or 0
  813.             if wq > 0 then
  814.                 o = (o and o .. "   " or "") .. wq .. " |T" .. (ci.iconFileID or "Interface/Icons/Temp") .. ":0|t"
  815.             end
  816.         end
  817.     end
  818.     return o
  819. end
  820. local function UButton_SetStartMode(self)
  821.     local tco = 0
  822.     for mid, nt in U.EnumerateTentativeGroups() do
  823.         tco = tco + nt + (C_Garrison.GetMissionCost(mid) or 0)
  824.     end
  825.     local anima = C_CurrencyInfo.GetCurrencyInfo(1813)
  826.     self.mode = anima and anima.quantity and anima.quantity >= tco and "start-send" or "start-cost"
  827. end
  828. local function UButton_Sync(self)
  829.     local ps = S[self:GetParent()]
  830.     if self == ps.StartButton then
  831.         return UButton_Sync(ps.UnButton)
  832.     end
  833.     local idm = U.HasDelayedStartMissions()
  834.     local ism = U.IsStartingMissions()
  835.     local icm = U.IsCompletingMissions()
  836.     local tg = U.HaveTentativeGroups()
  837.     self:Show()
  838.     if ism then
  839.         self:SetFormattedText(L"%d |4party:parties; remaining...", ism)
  840.         self.mode = "stop-send"
  841.     elseif idm then
  842.         self:SetFormattedText(L"Starting soon...")
  843.         self.mode = "stop-delayed-send"
  844.     elseif icm then
  845.         self:SetFormattedText(L"%d |4adventure:adventures; remaining...", icm)
  846.         self.mode = "stop-complete"
  847.     elseif ps and ps.hasCompletedMissions then
  848.         self:SetText(L"Complete All")
  849.         self.mode = "start-complete"
  850.     elseif tg then
  851.         self:SetText(L"Send Tentative Parties")
  852.         UButton_SetStartMode(self)
  853.     else
  854.         self.mode, self.clickWithEscape = nil, nil
  855.         self:Hide()
  856.     end
  857.     local ocwe = self.clickWithEscape
  858.     self.clickKey = self.mode ~= "start-send" and "SPACE" or nil
  859.     self.clickWithEscape = self.mode and self.mode:match("^stop%-") and true or nil
  860.     self.eatEscapeUntil = math.max(self.eatEscapeUntil or -math.huge, ocwe and self.clickWithEscape ~= ocwe and GetTime()+0.5 or -math.huge)
  861.     self.Glow:SetShown(self.mode == "stop-delayed-send")
  862.     if GameTooltip:IsOwned(self) then
  863.         local oe = self:GetScript("OnEnter")
  864.         if not self:IsVisible() then
  865.             GameTooltip:Hide()
  866.         elseif oe then
  867.             oe(self)
  868.         end
  869.     end
  870.     if self.mode == "start-complete" and tg then
  871.         UButton_SetStartMode(ps.StartButton)
  872.         ps.StartButton:Show()
  873.     else
  874.         ps.StartButton:Hide()
  875.     end
  876. end
  877. local function UButton_OnEnter(self)
  878.     local m = self.mode
  879.     if m == "start-send" or m == "stop-send" or m == "start-cost" then
  880.         GameTooltip:SetOwner(self, "ANCHOR_BOTTOM")
  881.         GameTooltip:AddLine(L"Send Tentative Parties")
  882.         local cb = C_CurrencyInfo.GetBasicCurrencyInfo(1813)
  883.         local curIco = cb and cb.icon and " |T" .. cb.icon .. ":0|t" or ""
  884.         local hadZH, hourglass = false, "|Tinterface/common/mini-hourglass:0:0:0:0:1:1:0:1:0:1:255:80:0|t "
  885.         local tco, ng = 0,0
  886.         for mid, nt, zeroHealth in U.EnumerateTentativeGroups() do
  887.             local co = C_Garrison.GetMissionCost(mid) or 0
  888.             hadZH = hadZH or zeroHealth
  889.             GameTooltip:AddDoubleLine((zeroHealth and hourglass or "") .. C_Garrison.GetMissionName(mid), (co+nt) .. curIco, 1,1,1, 1,1,1)
  890.             tco, ng = tco + co + nt, ng + 1
  891.         end
  892.         if ng > 1 then
  893.             local nc, ac = NORMAL_FONT_COLOR, m == "start-cost" and RED_FONT_COLOR or HIGHLIGHT_FONT_COLOR
  894.             GameTooltip:AddDoubleLine(TOTAL, tco .. curIco, nc.r, nc.g, nc.b, ac.r, ac.g, ac.b)
  895.         end
  896.         GameTooltip:AddLine(" ")
  897.         if m == "start-cost" then
  898.             GameTooltip:AddLine(L"Insufficient anima", 1, 0.5, 0)
  899.         end
  900.         if hadZH then
  901.             GameTooltip:AddLine(hourglass .. "|cffff8000" .. COVENANT_MISSIONS_COMPANIONS_MISSING_HEALTH, 1, 0.5, 0)
  902.             self.tooltipRefreshDelay = 10
  903.             self:SetScript("OnUpdate", CommonTooltip_DelayedRefresh_OnUpdate)
  904.         end
  905.         GameTooltip:AddLine("|TInterface/TUTORIALFRAME/UI-TUTORIAL-FRAME:14:12:0:-1:512:512:10:70:330:410|t " .. L"Clear all tentative parties", 0.5, 0.8, 1)
  906.         GameTooltip:Show()
  907.     elseif m == "start-complete" then
  908.         GameTooltip:SetOwner(self, "ANCHOR_BOTTOM")
  909.         GameTooltip:AddLine(L"Complete All")
  910.         local ct = C_Garrison.GetCompleteMissions(123)
  911.         for i=1, ct and #ct or 0 do
  912.             local m = ct[i]
  913.             GameTooltip:AddDoubleLine(m.name or "", getWastedRewards(m.rewards) or "", 1,1,1, 1,0,0)
  914.         end
  915.         GameTooltip:AddLine(" ")
  916.         GameTooltip:AddLine("|TInterface/TUTORIALFRAME/UI-TUTORIAL-FRAME:14:12:0:-1:512:512:10:70:330:410|t " .. COVENANT_MISSIONS_COMBAT_LOG_HEADER, 0.5, 0.8, 1)
  917.         GameTooltip:Show()
  918.     elseif m == "stop-delayed-send" then
  919.         GameTooltip:SetOwner(self, "ANCHOR_BOTTOM")
  920.         GameTooltip:AddLine(L"Starting soon...")
  921.         local cb = C_CurrencyInfo.GetBasicCurrencyInfo(1813)
  922.         local curIco = cb and cb.icon and " |T" .. cb.icon .. ":0|t" or ""
  923.         for mid, nt in U.EnumerateTentativeGroups() do
  924.             if U.IsMissionStartingSoon(mid) then
  925.                 local co = C_Garrison.GetMissionCost(mid) or 0
  926.                 GameTooltip:AddDoubleLine(C_Garrison.GetMissionName(mid), (co+nt) .. curIco, 1,1,1, 1,1,1)
  927.             end
  928.         end
  929.         GameTooltip:AddLine(" ")
  930.         GameTooltip:AddLine("|TInterface/TUTORIALFRAME/UI-TUTORIAL-FRAME:14:12:0:-1:512:512:10:70:330:410|t " .. COVENANT_MISSIONS_START_ADVENTURE, 0.5, 0.8, 1)
  931.         GameTooltip:Show()
  932.     end
  933. end
  934. local function UButton_OnClick(self, button)
  935.     local m, snd = self.mode, SOUNDKIT.U_CHAT_SCROLL_BUTTON
  936.     if U.IsStartingMissions() and m == "stop-send" then
  937.         U.StopStartingMissions()
  938.     elseif U.IsCompletingMissions() and m == "stop-complete" then
  939.         U.StopCompletingMissions()
  940.     elseif m == "stop-delayed-send" then
  941.         if button == "RightButton" then
  942.             U.RushDelayedStartMissions()
  943.         else
  944.             U.ClearDelayedStartMissions()
  945.             U.StopStartingMissions()
  946.             snd = 39514
  947.         end
  948.     elseif m == "start-complete" then
  949.         if button == "RightButton" then
  950.             U.InitiateMissionCompletion("first")
  951.         else
  952.             U.StartCompletingMissions()
  953.             if GameTooltip:IsOwned(self) then
  954.                 GameTooltip:Hide()
  955.             end
  956.         end
  957.     elseif U.HaveTentativeGroups() and m == "start-send" then
  958.         if button == "RightButton" then
  959.             U.DisbandTentativeGroups()
  960.         else
  961.             U.SendTentativeGroups()
  962.         end
  963.     end
  964.     PlaySound(snd)
  965.     UButton_Sync(self)
  966. end
  967. local function UButton_OnKeyDown(self, button)
  968.     if self:GetParent().keyFocus then
  969.         return
  970.     end
  971.     local click = button and button == self.clickKey
  972.     local abort = button == "ESCAPE" and self.clickWithEscape
  973.     local eatEsc = button == "ESCAPE" and self.eatEscapeUntil and self.eatEscapeUntil >= GetTime()
  974.     self:SetPropagateKeyboardInput(not (click or abort or eatEsc))
  975.     if click or abort then
  976.         self:Click()
  977.     end
  978. end
  979. local function Toast_Animate(self, elapsed)
  980.     local now, as, ap, d = GetTime(), self.animStart, self.animPhase
  981.     if as and elapsed > 0.04 then
  982.         as = as + elapsed - 0.04
  983.         self.animStart = as
  984.     end
  985.     if ap == nil then
  986.         self.animPhase, self.animStart = 1, nil
  987.         self:SetAlpha(0)
  988.         return
  989.     elseif as == nil then
  990.         self.animStart, as = now, now
  991.         self:SetAlpha(1)
  992.     end
  993.     d = now-as
  994.     if d < 0.5 then
  995.         self.PreGlow:SetAlpha(d < 0.25 and (d < 0.125 and d*8 or 2-d*8)*0.75 or 0)
  996.         self.Background:SetAlpha(d < 0.15 and sin(20+70*d/0.15) or 1)
  997.         self.Sheen:SetAlpha(sin(360*d))
  998.         self.Sheen:SetPoint("LEFT", 480*d, -1)
  999.     elseif d >= 4 then
  1000.         self:Hide()
  1001.     elseif self:IsMouseOver() then
  1002.         self.animStart = now-2
  1003.         if ap ~= 2 then
  1004.             self.animPhase = 2
  1005.             self.PreGlow:SetAlpha(0)
  1006.             self.Background:SetAlpha(1)
  1007.             self.Sheen:SetAlpha(0)
  1008.             self:SetAlpha(1)
  1009.         end
  1010.     elseif d >= 3 then
  1011.         self:SetAlpha(cos(90*(d-3)))
  1012.         self.animPhase = 3
  1013.     elseif ap ~= 2 then
  1014.         self.animPhase = 2
  1015.         self.PreGlow:SetAlpha(0)
  1016.         self.Background:SetAlpha(1)
  1017.         self.Sheen:SetAlpha(0)
  1018.     end
  1019. end
  1020. local function Toast_OnClick(self, button)
  1021.     if button == "RightButton" then
  1022.         self.animPhase, self.animStart = nil
  1023.         self:Hide()
  1024.     end
  1025. end
  1026. local function MissionPage_AcquireToast(self, followerMode)
  1027.     local toasts, toast = self.Toasts
  1028.     for i=1,#toasts do
  1029.         toast = toasts[i]
  1030.         if not toast:IsShown() then
  1031.             break
  1032.         end
  1033.         toast = nil
  1034.     end
  1035.     if not toast then
  1036.         toast = CreateObject("MissionToast", toasts[1]:GetParent())
  1037.         toast:SetPoint("TOP", toasts[#toasts], "BOTTOM", 0, -5)
  1038.         toasts[#toasts+1] = toast
  1039.     end
  1040.     followerMode = not not followerMode
  1041.     S[toast].Rewards.Container:SetWidth(38)
  1042.     S[toast].Rewards.Container:SetShown(not followerMode)
  1043.     toast.Portrait:SetShown(followerMode)
  1044.     toast.PortraitFrame:SetShown(followerMode)
  1045.     toast.animStart, toast.animPhase = nil
  1046.     toast:Show()
  1047.     return toast
  1048. end
  1049. local function MissionToast_CheckTooltip(tip, self)
  1050.     if (tip:GetLeft() or 2) < 1 then
  1051.         tip:ClearAllPoints()
  1052.         tip:SetPoint("LEFT", self, "RIGHT", self.tooltipFXO or 0, self.tooltipFYO or 0)
  1053.     end
  1054. end
  1055. local function cmpTimeLeft(a, b)
  1056.     if a.timeLeft ~= b.timeLeft then
  1057.         return a.timeLeft < b.timeLeft
  1058.     end
  1059.     return (a.name or "") < (b.name or "")
  1060. end
  1061. local function Common_RefreshTooltip(self)
  1062.     local rat = self.refreshAt
  1063.     local owned = rat and GameTooltip:IsOwned(self)
  1064.     if owned and rat > GetTime() then
  1065.         return
  1066.     end
  1067.     self.refreshAt = nil
  1068.     self:SetScript("OnUpdate", nil)
  1069.     if owned then
  1070.         self:GetScript("OnEnter")(self)
  1071.     end
  1072. end
  1073. local function AwayFollowers_OnEnter(self)
  1074.     GameTooltip:SetOwner(self, self.tooltipAnchor or "ANCHOR_TOP", self.tooltipXO or 0, self.tooltipYO or 0)
  1075.     GameTooltip:SetText(ITEM_QUALITY_COLORS[3].hex .. COVENANT_MISSION_FOLLOWER_CATEGORY)
  1076.     local ft, ct, nt = {}, C_Garrison.GetFollowers(123), 0
  1077.     for i=1,#ct do
  1078.         local ci = ct[i]
  1079.         if ci.status == GARRISON_FOLLOWER_ON_MISSION then
  1080.             ci.timeLeft = C_Garrison.GetFollowerMissionTimeLeftSeconds(ci.followerID) or 86400
  1081.             ft[#ft+1] = ci
  1082.         elseif U.FollowerHasTentativeGroup(ci.followerID) then
  1083.             nt = nt + 1
  1084.         end
  1085.     end
  1086.     table.sort(ft, cmpTimeLeft)
  1087.     local refNext = nil
  1088.     if #ft == 0 and nt == 0 then
  1089.         GameTooltip:AddLine(L'All companions are ready for adventures.', 1,1,1);
  1090.     elseif #ct ~= #ft or nt > 0 then
  1091.         GameTooltip:AddLine((L'%d |4companion is:companions are; ready for adventures.'):format(#ct-#ft), 1,1,1, 1)
  1092.     end
  1093.     if nt > 0 then
  1094.         GameTooltip:AddLine((L'%d |4companion is:companions are; in a tentative party.'):format(nt), 1,1,1, 1)
  1095.     end
  1096.     if #ft > 0 then
  1097.         if GameTooltip:NumLines() > 1 then
  1098.             GameTooltip:AddLine(" ")
  1099.         end
  1100.         GameTooltip:AddLine(L"Returning soon:")
  1101.         for i=1,#ft do
  1102.             local fi = ft[i]
  1103.             local nr, tl = (fi.timeLeft + 59.998) % 60, U.GetTimeStringFromSeconds(fi.timeLeft, false, true, true)
  1104.             refNext = refNext and refNext <= nr and refNext or nr
  1105.             GameTooltip:AddDoubleLine("|cff909090[" .. fi.level .. "]|r|cffffffff " .. fi.name, NORMAL_FONT_COLOR_CODE .. " " .. (tl or ""))
  1106.         end
  1107.     end
  1108.     self.refreshAt = refNext and (GetTime() + refNext)
  1109.     self:SetScript("OnUpdate", Common_RefreshTooltip)
  1110.     GameTooltip:Show()
  1111. end
  1112.  
  1113. do -- Factory.ObjectGroup
  1114.     local NamedMethodCallCache = setmetatable({}, {__index=function(t,k)
  1115.         t[k] = function(self, ...)
  1116.             for i=1,#self do
  1117.                 local o = self[i]
  1118.                 securecall(o[k], o, ...)
  1119.             end
  1120.         end
  1121.         return t[k]
  1122.     end})
  1123.     local ObjectGroup_Meta = {__index=function(t,k)
  1124.         if type(k) == "string" and type(t[1]) == "table" and type(t[1][k]) == "function" then
  1125.             t[k] = NamedMethodCallCache[k]
  1126.             return t[k]
  1127.         end
  1128.     end}
  1129.     function Factory.ObjectGroup(...)
  1130.         return setmetatable(type((...)) == "table" and ... or {...}, ObjectGroup_Meta)
  1131.     end
  1132. end
  1133.  
  1134. function Factory.PanelButton(parent)
  1135.     local r = CreateFrame("Button", nil, parent, "UIPanelButtonNoTooltipTemplate")
  1136.     r:SetHeight(UIBUTTON_HEIGHT)
  1137.     r:SetPushedTextOffset(-1, -1)
  1138.     return r
  1139. end
  1140. function Factory.PanelButtonGlow(p)
  1141.     local ex, ey, w = 6, 6, 16
  1142.     local g = CreateFrame("Frame", nil, p)
  1143.     g:SetFlattensRenderLayers(true)
  1144.     local t = g:CreateTexture(nil, "BACKGROUND", nil, -1)
  1145.     g:SetAllPoints()
  1146.     t:SetTexture("Interface/Buttons/UI-Panel-Button-Glow")
  1147.     t:SetPoint("TOPLEFT", -ex, ey)
  1148.     t:SetPoint("BOTTOMRIGHT", g, "BOTTOMLEFT", w-ex, -ey)
  1149.     t:SetTexCoord(0, 20/128, 0, 38/64)
  1150.     t:SetBlendMode("ADD")
  1151.     t, g[1] = g:CreateTexture(nil, "BACKGROUND", nil, -1)
  1152.     t:SetTexture("Interface/Buttons/UI-Panel-Button-Glow")
  1153.     t:SetPoint("TOPRIGHT", ex, ey)
  1154.     t:SetPoint("BOTTOMLEFT", g, "BOTTOMRIGHT", ex-w, -ey)
  1155.     t:SetTexCoord(75/128, 95/128, 0, 38/64)
  1156.     t:SetBlendMode("ADD")
  1157.     t, g[2] = g:CreateTexture(nil, "BACKGROUND", nil, -1)
  1158.     t:SetTexture("Interface/Buttons/UI-Panel-Button-Glow")
  1159.     t:SetPoint("TOPLEFT", w-ex, ey)
  1160.     t:SetPoint("BOTTOMRIGHT", ex-w, -ey)
  1161.     t:SetTexCoord(20/128, 75/128, 0, 38/64)
  1162.     t:SetBlendMode("ADD")
  1163.     g[3] = t
  1164.     local ag = g:CreateAnimationGroup()
  1165.     ag:SetLooping("BOUNCE")
  1166.     local aa = ag:CreateAnimation("Alpha")
  1167.     aa:SetFromAlpha(0.15)
  1168.     aa:SetToAlpha(0.75)
  1169.     aa:SetDuration(0.8)
  1170.     aa:SetSmoothing("IN_OUT")
  1171.     ag:Play()
  1172.     return g
  1173. end
  1174. function Factory.RaisedBorder(parent)
  1175.     local border = CreateFrame("Frame", nil, parent)
  1176.     border:SetPoint("TOPLEFT", 0, 8)
  1177.     border:SetPoint("BOTTOMRIGHT", 0, -4)
  1178.     do
  1179.         local t = border:CreateTexture(nil, "BACKGROUND")
  1180.         t:SetPoint("TOPLEFT", 0, 2)
  1181.         t:SetPoint("TOPRIGHT", 0, 2)
  1182.         t:SetHeight(12)
  1183.         t:SetTexture("Interface/Garrison/AdventureMissionsFrameHorizontal")
  1184.         t:SetTexCoord(0,1, 67/128, 79/128)
  1185.         t = border:CreateTexture(nil, "BACKGROUND")
  1186.         t:SetPoint("BOTTOMLEFT", 0, -2)
  1187.         t:SetPoint("BOTTOMRIGHT", 0, -2)
  1188.         t:SetHeight(12)
  1189.         t:SetTexture("Interface/Garrison/AdventureMissionsFrameHorizontal")
  1190.         t:SetTexCoord(0,1, 79/128, 67/128)
  1191.         t = border:CreateTexture(nil, "BACKGROUND")
  1192.         t:SetPoint("TOPLEFT", -1, 0)
  1193.         t:SetPoint("BOTTOMLEFT", -1, 0)
  1194.         t:SetWidth(12)
  1195.         t:SetTexture("Interface/Garrison/AdventureMissionsFrameVert")
  1196.         t:SetTexCoord(85/128, 97/128, 0, 1)
  1197.         t = border:CreateTexture(nil, "BACKGROUND")
  1198.         t:SetPoint("TOPRIGHT", 1, 0)
  1199.         t:SetPoint("BOTTOMRIGHT", 1, 0)
  1200.         t:SetWidth(12)
  1201.         t:SetTexture("Interface/Garrison/AdventureMissionsFrameVert")
  1202.         t:SetTexCoord(67/128, 79/128, 0, 1)
  1203.         t = border:CreateTexture(nil, "BACKGROUND", nil, 1)
  1204.         t:SetSize(42, 42)
  1205.         t:SetPoint("TOPLEFT")
  1206. --      t:SetTexture("Interface/Garrison/AdventureMissionsFrame")
  1207.         t:SetTexCoord(650/1024, 688/1024, 1119/2048, 1158/2048)
  1208.         t = border:CreateTexture(nil, "BACKGROUND", nil, 1)
  1209.         t:SetSize(42, 42)
  1210.         t:SetPoint("TOPRIGHT")
  1211. --      t:SetTexture("Interface/Garrison/AdventureMissionsFrame")
  1212.         t:SetTexCoord(650/1024, 688/1024, 1119/2048, 1158/2048)
  1213.         Mirror(t, true, false)
  1214.         t = border:CreateTexture(nil, "BACKGROUND", nil, 1)
  1215.         t:SetSize(42, 42)
  1216.         t:SetPoint("BOTTOMLEFT")
  1217. --      t:SetTexture("Interface/Garrison/AdventureMissionsFrame")
  1218.         t:SetTexCoord(650/1024, 688/1024, 1119/2048, 1158/2048)
  1219.         Mirror(t, false, true)
  1220.         t = border:CreateTexture(nil, "BACKGROUND", nil, 1)
  1221.         t:SetSize(42, 42)
  1222.         t:SetPoint("BOTTOMRIGHT")
  1223. --      t:SetTexture("Interface/Garrison/AdventureMissionsFrame")
  1224.         t:SetTexCoord(650/1024, 688/1024, 1119/2048, 1158/2048)
  1225.         Mirror(t, true, true)
  1226.         t = parent:CreateTexture(nil, "BACKGROUND", nil, -2)
  1227.         t:SetTexture("Interface/FrameGeneral/UIFrame"..CovenKit.."Background", true, true)
  1228.         t:SetHorizTile(true)
  1229.         t:SetVertTile(true)
  1230.         t:SetAllPoints(border)
  1231.         t:SetVertexColor(0.95, 0.95, 0.95)
  1232.         t = parent:CreateTexture(nil, "BACKGROUND", nil, -1)
  1233.         t:SetAtlas("Adventures-Missions-Shadow")
  1234.         t:SetAllPoints(border)
  1235.         t:SetAlpha(0.45)
  1236.     end
  1237. end
  1238. function Factory.LockedCopyInputBox(parent)
  1239.     local f = CreateFrame("EditBox", nil, parent, "InputBoxTemplate")
  1240.     f:SetHighlightColor(1,0.8,0.3, 0.6)
  1241.     f:SetScript("OnEscapePressed", f.ClearFocus)
  1242.     f:SetScript("OnTextChanged", LockedInputBox_OnTextChanged)
  1243.     f:SetAutoFocus(false)
  1244.     f:SetSize(250, 20)
  1245.     return f
  1246. end
  1247. function Factory.CopyBoxUI(parent)
  1248.     local f = CreateFrame("Frame", nil, parent)
  1249.     f:SetSize(335, 340)
  1250.     f:SetFrameLevel(600)
  1251.     f:SetPoint("CENTER")
  1252.     local fbg = CreateFrame("Button", nil, f)
  1253.     fbg:SetAllPoints(parent)
  1254.     fbg:SetScript("OnMouseWheel", function() end)
  1255.     fbg:SetScript("OnClick", function() if not f:IsMouseOver(0, 0, -10, 10) then f:Hide() end end)
  1256.     fbg:RegisterForClicks("AnyUp")
  1257.     fbg:EnableMouse(true)
  1258.     fbg:SetFrameLevel(500)
  1259.     local t = fbg:CreateTexture(nil, "BACKGROUND")
  1260.     t:SetColorTexture(0,0,0,0.9)
  1261.     t:SetAllPoints()
  1262.     t = f:CreateTexture(nil, "BACKGROUND")
  1263.     t:SetAtlas("UI-Frame-"..CovenKit.."-CardParchmentWider")
  1264.     t:SetAllPoints()
  1265.     t = f:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge2")
  1266.     t:SetText("Moonkittens for sale")
  1267.     t:SetPoint("TOP", 0, -34)
  1268.     t, f.Title = f:CreateFontString(nil, "OVERLAY", "GameFontBlackMedium"), t
  1269.     t:SetWidth(270)
  1270.     t:SetPoint("TOP", f.Title, "BOTTOM", 0, -10)
  1271.     t:SetJustifyH("LEFT")
  1272.     t:SetTextColor(0.1, 0.1, 0.1)
  1273.     t:SetText("These adorable rascals are guaranteed to moonfire literally everything around them.");
  1274.     t, f.Intro = f:CreateFontString(nil, "OVERLAY", "GameFontBlackMedium"), t
  1275.     t:SetWidth(270)
  1276.     t:SetJustifyH("LEFT")
  1277.     t:SetText("1. Moonfire.")
  1278.     t:SetTextColor(0.1, 0.1, 0.1)
  1279.     local ub = CreateObject("LockedCopyInputBox", f)
  1280.     ub:SetPoint("TOP", f.Intro, "BOTTOM", 0, -60)
  1281.     ub:SetText("Very moon,")
  1282.     ub:SetTextColor(0.25, 0.75, 1)
  1283.     t:SetPoint("BOTTOM", ub, "TOP", 0, 6)
  1284.     f.FirstInputBox = ub
  1285.     f.FirstInputBoxLabel = t
  1286.  
  1287.     local cb = CreateObject("LockedCopyInputBox", f)
  1288.     cb:SetPoint("TOP", ub, "TOP", 0, -50)
  1289.     cb:SetText("Much fire!")
  1290.     f.SecondInputBox = cb
  1291.     t = f:CreateFontString(nil, "OVERLAY", "GameFontBlackMedium")
  1292.     t:SetWidth(270)
  1293.     t:SetJustifyH("LEFT")
  1294.     t:SetPoint("BOTTOM", cb, "TOP", 0, 6)
  1295.     t:SetText("2. Kittens.")
  1296.     t:SetTextColor(0.1, 0.1, 0.1)
  1297.     f.SecondInputBoxLabel = t
  1298.  
  1299.     f:SetScript("OnKeyDown", function(self, key)
  1300.         f:SetPropagateKeyboardInput(key ~= "ESCAPE")
  1301.         if key == "ESCAPE" then
  1302.             self:Hide()
  1303.         end
  1304.     end)
  1305.  
  1306.     t = CreateObject("PanelButton", f)
  1307.     t:SetPoint("BOTTOM", 0, 34 + (UIBUTTON_HEIGHT-22)/2)
  1308.     t:SetWidth(216)
  1309.     t:SetText("Reset")
  1310.     t, f.ResetButton = CreateFrame("Button", nil, f, "UIPanelCloseButtonNoScripts"), t
  1311.     t:SetPoint("TOPRIGHT", -8, -8)
  1312.     t:SetScript("OnClick", function()
  1313.         f:Hide()
  1314.     end)
  1315.     t, f.CloseButton2 = f:CreateFontString(nil, "OVERLAY", "GameFontBlackSmall"), t
  1316.     t:SetPoint("BOTTOMRIGHT", -16, 14)
  1317.     t:SetText(GetAddOnMetadata(AN, "Title") .. " v" .. GetAddOnMetadata(AN, "Version"))
  1318.     f.VersionText = t
  1319.  
  1320.     f:SetScript("OnHide", function(self)
  1321.         if self:IsShown() then
  1322.             self:Hide()
  1323.         else
  1324.             PlaySound(170568)
  1325.         end
  1326.         if self:GetParent().keyFocus == self then
  1327.             self:GetParent().keyFocus = nil
  1328.         end
  1329.     end)
  1330.     f:SetScript("OnShow", function(self)
  1331.         self:GetParent().keyFocus = self
  1332.     end)
  1333.  
  1334.     return f
  1335. end
  1336. function Factory.MissionPage(parent)
  1337.     local f = CreateFrame("Frame", nil, parent)
  1338.     local s = CreateObject("Shadow", f)
  1339.     f:SetAllPoints()
  1340.     f:EnableMouse(true)
  1341.     s.MissionList = CreateObject("MissionList", f)
  1342.     s.CopyBox = CreateObject("CopyBoxUI", f)
  1343.     s.CopyBox:Hide()
  1344.     local resButton = CreateObject("ResourceButton", f, 1813) do
  1345.         s.ResourceCounter = resButton
  1346.         resButton:SetPoint("TOPRIGHT", -72, -30)
  1347.     end
  1348.     local ccButton = CreateObject("ILButton", f) do
  1349.         s.CompanionCounter = ccButton
  1350.         ccButton.Icon:SetTexture("Interface/FriendsFrame/Battlenet-Battleneticon")
  1351.         ccButton.Icon:SetTexCoord(6/32,26/32, 6/32,26/32)
  1352.         ccButton.Icon:SetBlendMode("ADD")
  1353.         ccButton:SetPoint("RIGHT", resButton, "LEFT", -30, 0)
  1354.         ccButton:SetScript("OnEnter", AwayFollowers_OnEnter)
  1355.     end
  1356.     local prButton = CreateObject("ResourceButton", f, 1889) do
  1357.         s.ProgressCounter = prButton
  1358.         prButton:SetPoint("RIGHT", ccButton, "LEFT", -35, 0)
  1359.     end
  1360.     local logsButton = CreateObject("ILButton", f, 1889) do
  1361.         s.LogCounter = logsButton
  1362.         logsButton:RegisterForClicks("LeftButtonUp", "RightButtonUp")
  1363.         logsButton.Icon:SetTexture("Interface/Icons/INV_Inscription_80_Scroll")
  1364.         logsButton:SetPoint("RIGHT", prButton, "LEFT", -35, 0)
  1365.     end
  1366.     local uButton = CreateObject("PanelButton", f) do
  1367.         s.UnButton, uButton.Glow = uButton, CreateObject("PanelButtonGlow", uButton)
  1368.         uButton:SetWidth(200)
  1369.         uButton:SetPoint("TOPLEFT", 200, -34)
  1370.         uButton:Hide()
  1371.         uButton:RegisterForClicks("LeftButtonUp", "RightButtonUp")
  1372.         uButton:SetScript("OnEnter", UButton_OnEnter)
  1373.         uButton:SetScript("OnClick", UButton_OnClick)
  1374.         uButton:SetScript("OnLeave", HideOwnGameTooltip)
  1375.         uButton:SetScript("OnKeyDown", UButton_OnKeyDown)
  1376.         uButton.Sync = UButton_Sync
  1377.     end
  1378.     local sButton = CreateObject("PanelButton", f) do
  1379.         s.StartButton = sButton
  1380.         sButton:Hide()
  1381.         sButton:SetWidth(26)
  1382.         sButton:SetPoint("LEFT", uButton, "RIGHT", 4, 0)
  1383.         sButton:RegisterForClicks("LeftButtonUp", "RightButtonUp")
  1384.         sButton:SetScript("OnEnter", UButton_OnEnter)
  1385.         sButton:SetScript("OnClick", UButton_OnClick)
  1386.         sButton:SetScript("OnLeave", HideOwnGameTooltip)
  1387.         sButton:SetText("|TInterface/RaidFrame/UI-RaidFrame-Arrow:22:30:-3:-1|t")
  1388.     end
  1389.     local vButton = CreateObject("CommonHoverTooltip", CreateFrame("Button", nil, f)) do
  1390.         s.Version = vButton
  1391.         vButton:Disable()
  1392.         vButton:SetMotionScriptsWhileDisabled(true)
  1393.         local an = GetAddOnMetadata(AN, "Title") or AN or ""
  1394.         local av = GetAddOnMetadata(AN, "Version") or "Q"
  1395.         local aw = GetAddOnMetadata(AN, "X-Website")
  1396.         vButton:SetPoint("BOTTOMRIGHT", -62, 20)
  1397.         vButton:SetSize(110, 20)
  1398.         vButton:SetPushedTextOffset(0,0)
  1399.         vButton:SetNormalFontObject(GameFontNormalSmall)
  1400.         vButton:SetDisabledFontObject(GameFontNormalSmall)
  1401.         vButton:SetText("|cff787878" .. an .. " |r|cffb0b0b0" .. av)
  1402.         local fs = vButton:GetFontString()
  1403.         fs:ClearAllPoints()
  1404.         fs:SetPoint("RIGHT")
  1405.         vButton.tooltipHeader, vButton.tooltipTextNW, vButton.tooltipAnchor = an, true, "ANCHOR_TOPRIGHT"
  1406.         vButton.tooltipText = aw and "|cff20a0ff" .. aw or nil
  1407.     end
  1408.     s.Toasts = {CreateObject("MissionToast", f)}
  1409.     s.Toasts[1]:SetPoint("TOPLEFT", 20, -62)
  1410.     s.AcquireToast = MissionPage_AcquireToast
  1411.     return s
  1412. end
  1413. function Factory.MissionList(parent)
  1414.     local coven = C_Covenants.GetCovenantData(C_Covenants.GetActiveCovenantID() or 1)
  1415.     CovenKit = coven and coven.textureKit or "NightFae"
  1416.  
  1417.     local missionList = CreateFrame("ScrollFrame", nil, parent)
  1418.     local s = CreateObject("Shadow", missionList)
  1419.     missionList:SetSize(892, 524)
  1420.     missionList:SetPoint("TOP", 0, -72)
  1421.     missionList:EnableMouseWheel(true)
  1422.     missionList.ScrollToward = MissionList_ScrollToward
  1423.     CreateObject("RaisedBorder", missionList)
  1424.     do -- missionList:OnMouseWheel
  1425.         local v = CreateFrame("Frame", nil, parent)
  1426.         v:SetAllPoints(missionList)
  1427.         v:EnableMouse(true)
  1428.         v:SetFrameLevel(parent:GetFrameLevel()+20)
  1429.         v:Hide()
  1430.         s.ScrollVeil = v
  1431.         local function scrollFinish(self)
  1432.             local se = S[self]
  1433.             self:GetScrollChild():SetPoint("TOPLEFT", 0, se.scrollEnd)
  1434.             se.scrollStart, se.scrollEnd, se.scrollTimeStart, se.scrollTimeEnd, se.scrollSpeed, se.scrollLast = nil
  1435.             self:SetScript("OnUpdate", nil)
  1436.             self:SetScript("OnHide", nil)
  1437.             se.ScrollVeil:Hide()
  1438.         end
  1439.         local function scrollOnUpdate(self)
  1440.             local se = S[self]
  1441.             local a, b, s, t = se.scrollStart, se.scrollEnd, se.scrollTimeStart, se.scrollTimeEnd
  1442.             local sc, c = self:GetScrollChild(), GetTime()
  1443.             if c >= t then
  1444.                 scrollFinish(self)
  1445.             else
  1446.                 local p = a + (b-a)*(c-s)/(t-s)
  1447.                 sc:SetPoint("TOPLEFT", 0, p)
  1448.                 se.scrollLastTime, se.scrollLastOffset = c, s
  1449.             end
  1450.         end
  1451.         local function onMouseWheel(self, d)
  1452.             local se, y = S[self], select(5, self:GetScrollChild():GetPoint())
  1453.             local snap = math.min(math.max(0, (se.scrollSnap or 0) - d), math.floor(((se.numMissions or 0)-1)/3)-1)
  1454.             local dy = snap == 0 and 0 or (195*snap-30)
  1455.             if se.scrollEnd ~= dy then
  1456.                 local ct = GetTime()
  1457.                 se.scrollSnap, se.scrollStart, se.scrollEnd, se.scrollTimeStart, se.scrollTimeEnd = snap, y, dy, ct, ct + 0.20
  1458.                 self:SetScript("OnUpdate", scrollOnUpdate)
  1459.                 self:SetScript("OnHide", scrollFinish)
  1460.                 S[self].ScrollVeil:Show()
  1461.             end
  1462.         end
  1463.         missionList:SetScript("OnMouseWheel", onMouseWheel)
  1464.         missionList:SetScript("OnKeyDown", function(self, k)
  1465.             self:SetPropagateKeyboardInput(true)
  1466.             if k == "PAGEDOWN" or k == "PAGEUP" then
  1467.                 self:SetPropagateKeyboardInput(false)
  1468.                 onMouseWheel(self, k == "PAGEDOWN" and -2 or 2)
  1469.             elseif k == "HOME" or k == "END" then
  1470.                 self:SetPropagateKeyboardInput(false)
  1471.                 onMouseWheel(self, k == "END" and -math.huge or math.huge)
  1472.             end
  1473.         end)
  1474.         function missionList:ReturnToTop()
  1475.             local se = S[self]
  1476.             se.scrollSnap, se.scrollEnd = 0, 0
  1477.             scrollFinish(self)
  1478.         end
  1479.         function missionList:CheckScrollRange()
  1480.             onMouseWheel(self, 0)
  1481.         end
  1482.     end
  1483.     local scrollChild = CreateFrame("Frame", nil, missionList)
  1484.     scrollChild:SetPoint("TOPLEFT")
  1485.     scrollChild:SetSize(902,missionList:GetHeight())
  1486.     missionList:SetScrollChild(scrollChild)
  1487.     s.Missions = setmetatable({}, {__index=MissionList_SpawnMissionButton, __metatable=false})
  1488.     for i=1,6 do
  1489.         local cf = CreateObject("MissionButton", scrollChild)
  1490.         s.Missions[i] = cf
  1491.         cf:SetPoint("TOPLEFT", 292*(((i-1)%3)+1)-284, math.floor((i-1)/3) *- 195)
  1492.     end
  1493.  
  1494.     return s
  1495. end
  1496. function Factory.MissionButton(parent)
  1497.     local cf, t = CreateFrame("Button", nil, parent)
  1498.     local s = CreateObject("Shadow", cf)
  1499.     cf:SetSize(290, 196)
  1500.     cf:SetScript("OnClick", MissionButton_OnClick)
  1501.     t = cf:CreateTexture(nil, "BACKGROUND", nil, -2)
  1502.     t:SetAtlas("UI-Frame-"..CovenKit.."-CardParchmentWider")
  1503.     t:SetPoint("TOPLEFT", 0, -24)
  1504.     t:SetPoint("BOTTOMRIGHT", 0, 0)
  1505.     Mirror(t, true)
  1506.     t = cf:CreateTexture(nil, "ARTWORK", nil, -6)
  1507.     t:SetAtlas("UI-Frame-"..CovenKit.."-CardParchmentWider")
  1508.     t:SetPoint("TOPLEFT", 0, -24)
  1509.     t:SetPoint("BOTTOMRIGHT", 0, 0)
  1510.     t:SetVertexColor(0.30, 0.30, 0.40, 0.60)
  1511.     Mirror(t, true)
  1512.     t, s.Veil = cf:CreateFontString(nil, "BACKGROUND", "GameFontHighlightLarge"), t
  1513.     t:SetText("Beast Beneath the Hydrant")
  1514.     t:SetPoint("TOP", 0, -55.5)
  1515.     t:SetWidth(276)
  1516.     t:SetTextColor(0.97, 0.94, 0.70)
  1517.     t, s.Name = cf:CreateTexture(nil, "BACKGROUND", nil, 2), t
  1518.     t:SetAtlas("Campaign-QuestLog-LoreDivider")
  1519.     local divC = CovenKit == "Kyrian" and 0xfeb0a0 or CovenKit == "Venthyr" and 0xfe40f0 or CovenKit == "Necrolord" and 0xc0fe00 or 0x4080fe
  1520.     t:SetVertexColor(divC / 2^24, divC/256 % 256 / 255, divC%256/255)
  1521.     t:SetWidth(286)
  1522.     t:SetPoint("TOP", s.Name, 0, 6)
  1523.     t:SetPoint("BOTTOM", s.Name, "BOTTOM", 0, -5)
  1524.     t = cf:CreateFontString(nil, "OVERLAY", "GameFontBlack")
  1525.     t:SetWidth(262)
  1526.     t:SetPoint("TOP", s.Name, "BOTTOM", 0, -28.5)
  1527.     t:SetText("Nyar!")
  1528.     t, s.Description = CreateObject("CommonHoverTooltip", CreateFrame("Button", nil, cf)), t
  1529.     t:SetNormalFontObject(GameFontBlack)
  1530.     t:SetSize(40, 16)
  1531.     t:SetPoint("BOTTOMLEFT", cf, 14, 13)
  1532.     t:SetText("Expired")
  1533.     t:GetFontString():SetJustifyH("LEFT")
  1534.     t:SetMouseClickEnabled(false)
  1535.     s.ExpireTime = t
  1536.     CreateObject("CountdownText", cf, s.ExpireTime)
  1537.     s.Rewards = CreateObject("RewardBlock", cf, 48, 4)
  1538.     s.Rewards.Container:SetPoint("TOP", 0, -4)
  1539.     t = CreateObject("AchievementRewardIcon", cf)
  1540.     t:SetPoint("RIGHT", cf, "TOPRIGHT", -25, -40)
  1541.     s.AchievementReward = t
  1542.  
  1543.     t = CreateFrame("Frame", nil, cf)
  1544.     t:SetPoint("TOP", s.Name, "BOTTOM", 0, -6)
  1545.     t:SetSize(224, 20)
  1546.     local a, b = cf:CreateTexture(nil, "BACKGROUND", nil, 2)
  1547.     a:SetAtlas("ui_adv_health", true)
  1548.     a:SetPoint("LEFT", t, "LEFT", -6, 0)
  1549.     b = t:CreateFontString(nil, "OVERLAY", "GameFontBlack")
  1550.     b:SetPoint("LEFT", a, "RIGHT", -2, 0)
  1551.     b:SetText("2,424")
  1552.     a, s.enemyHP = cf:CreateTexture(nil, "BACKGROUND", nil, 2), b
  1553.     a:SetAtlas("ui_adv_atk", true)
  1554.     a:SetPoint("LEFT", b, "RIGHT", 0, 0)
  1555.     b = t:CreateFontString(nil, "OVERLAY", "GameFontBlack")
  1556.     b:SetPoint("LEFT", a, "RIGHT", -2, 0)
  1557.     b:SetText("2,424")
  1558.     a, s.enemyATK = cf:CreateTexture(nil, "BACKGROUND", nil, 2), b
  1559.     a:SetAtlas("animachannel-bar-" .. CovenKit .. "-gem", true)
  1560.     a:SetPoint("LEFT", b, "RIGHT", 8, 0)
  1561.     b = t:CreateFontString(nil, "OVERLAY", "GameFontBlack")
  1562.     b:SetPoint("LEFT", a, "RIGHT", -2, 0)
  1563.     b:SetText("42")
  1564.     a, s.animaCost = cf:CreateTexture(nil, "BACKGROUND", nil, 2), b
  1565.     a:SetTexture("Interface/Common/Mini-hourglass")
  1566.     a:SetSize(14, 14)
  1567.     a:SetVertexColor(0.5, 0.75, 1)
  1568.     a:SetPoint("LEFT", b, "RIGHT", 8, 0)
  1569.     b = t:CreateFontString(nil, "OVERLAY", "GameFontBlack")
  1570.     b:SetPoint("LEFT", a, "RIGHT", 2, 0)
  1571.     s.duration = b
  1572.     s.statLine = t
  1573.  
  1574.     t = CreateObject("ProgressBar", cf)
  1575.     t:SetWidth(cf:GetWidth()-50)
  1576.     t:SetPoint("BOTTOM", 0, 14)
  1577.     t:SetHitRectInsets(-6, -6, -6, -6)
  1578.     t.Fill:SetAtlas("UI-Frame-Bar-Fill-Blue")
  1579.     t:SetScript("OnClick", MissionButton_OnProgressBarClick)
  1580.     s.ProgressBar = t
  1581.     local gb = CreateObject("PanelButton", cf)
  1582.     gb:SetPoint("BOTTOM", 20, 10)
  1583.     gb:SetText("Buttons!")
  1584.     gb:SetWidth(165)
  1585.     gb:RegisterForClicks("LeftButtonUp", "RightButtonUp")
  1586.     gb:SetScript("OnClick", MissionButton_OnViewClick)
  1587.     s.ViewButton = gb
  1588.     t = CreateObject("PanelButton", cf)
  1589.     t:SetPoint("RIGHT", s.ViewButton, "LEFT", -8)
  1590.     t:SetWidth(24)
  1591.     t:SetText("|TInterface/EncounterJournal/UI-EJ-HeroicTextIcon:0|t")
  1592.     t:SetPushedTextOffset(-1, -1)
  1593.     t:RegisterForClicks("LeftButtonUp", "RightButtonUp")
  1594.     t:SetScript("OnEnter", DoomRun_OnEnter)
  1595.     t:SetScript("OnLeave", HideOwnGameTooltip)
  1596.     t:SetScript("OnClick", DoomRun_OnClick)
  1597.     t:SetScript("OnShow", DoomRun_OnShow)
  1598.     t, s.DoomRunButton = CreateObject("PanelButton", cf), t
  1599.     t:SetAllPoints(s.DoomRunButton)
  1600.     t:SetText("|TInterface/Buttons/UI-StopButton:0|t")
  1601.     t:SetScript("OnClick", TentativeGroupClear_OnClick)
  1602.     t:SetPushedTextOffset(-1, -1)
  1603.     s.TentativeClear = t
  1604.     t = cf:CreateFontString(nil, "BACKGROUND", "GameFontNormalSmall")
  1605.     t:SetTextColor(0.97, 0.94, 0.70)
  1606.     t:SetPoint("TOPLEFT", 16, -38)
  1607.     t, s.TagText = CreateObject("BoardGroup", cf), t
  1608.     t:SetWidth(272)
  1609.     t:SetPoint("TOP", s.Name, "BOTTOM", 0, -24)
  1610.     t:SetPoint("BOTTOM", 0, 37)
  1611.     s.Group = t
  1612.     s.SetGroupPortraits = MissionButton_SetGroupPortraits
  1613.  
  1614.     return cf
  1615. end
  1616. function Factory.BoardGroup(parent)
  1617.     local f, t, r = CreateFrame("Frame", nil, parent)
  1618.     local s = CreateObject("Shadow", f)
  1619.     for i=0,4 do
  1620.         t = f:CreateTexture(nil, "ARTWORK", nil, 1)
  1621.         r = f:CreateTexture(nil, "ARTWORK", nil, 2)
  1622.         t:SetSize(36, 36)
  1623.         r:SetAtlas("GarrMission_PortraitRing_Enemy")
  1624.         r:SetPoint("TOPRIGHT", t, "TOPRIGHT", 3.5, 3.5)
  1625.         r:SetPoint("BOTTOMLEFT", t, "BOTTOMLEFT", -3.5, -3.5)
  1626.         s[i], s[5+i] = t, r
  1627.     end
  1628.     s[0]:SetPoint("BOTTOM", -44, 5)
  1629.     s[1]:SetPoint("BOTTOM", 44, 5)
  1630.     s[2]:SetPoint("TOP", -88, -5)
  1631.     s[3]:SetPoint("TOP", 0, -5)
  1632.     s[4]:SetPoint("TOP", 88, -5)
  1633.     return f
  1634. end
  1635. function Factory.RewardFrame(parent, sz)
  1636.     sz = sz or 48
  1637.     local f, t = CreateObject("CommonHoverTooltip", CreateFrame("Button", nil, parent))
  1638.     f:SetSize(sz, sz)
  1639.     t = f:CreateTexture(nil, "ARTWORK")
  1640.     local o = sz*6/64
  1641.     t:SetPoint("TOPLEFT", o, -o)
  1642.     t:SetPoint("BOTTOMRIGHT", -o, o)
  1643.     t:SetTexture("Interface/Icons/Temp")
  1644.     t:SetTexCoord(4/64, 60/64, 4/64, 60/64)
  1645.     t, f.Icon = f:CreateTexture(nil, "ARTWORK", nil, 2), t
  1646.     t:SetAllPoints()
  1647.     t:SetAtlas("loottoast-itemborder-orange")
  1648.     t, f.RarityBorder = f:CreateFontString(nil, "OVERLAY", "GameFontHighlightOutline"), t
  1649.     t:SetPoint("BOTTOMRIGHT", -4, 5)
  1650.     f.Quantity = t
  1651.     f:SetScript("OnClick", CommonLinkable_OnClick)
  1652.     f.SetReward = RewardButton_SetReward
  1653.     return f
  1654. end
  1655. function Factory.RewardBlock(parent, sz, sp)
  1656.     local t, s, r = CreateFrame("Frame", nil, parent), sz+(sp or 3)
  1657.     t:SetSize(s+sz, sz)
  1658.     r = {Container=t, SetRewards=RewardBlock_SetRewards}
  1659.     for j=1,3 do
  1660.         local rew = CreateObject("RewardFrame", t, sz)
  1661.         rew:SetPoint("LEFT", s*j-s, 0)
  1662.         r[j] = rew
  1663.     end
  1664.     return r
  1665. end
  1666. function Factory.InlineRewardBlock(parent)
  1667.     local f, t = CreateFrame("Frame", nil, parent)
  1668.     f:EnableMouse(true)
  1669.     f:SetSize(140, 28)
  1670.     t = f:CreateFontString(nil, "OVERLAY", "GameFontNormal")
  1671.     t:SetPoint("LEFT")
  1672.     t:SetText(L"Rewards:")
  1673.     f.Rewards = {Label=t}
  1674.     for i=1,3 do
  1675.         t = CreateObject("RewardFrame", f, 28)
  1676.         t:SetPoint("LEFT", f.Rewards[i-1] or f.Rewards.Label, "RIGHT", i == 1 and 12 or 4, 0)
  1677.         t.Quantity:Hide()
  1678.         t.ShowQuantityFromWidgetText = "Quantity"
  1679.         f.Rewards[i] = t
  1680.     end
  1681.     f.Rewards.SetRewards = RewardBlock_SetRewards
  1682.     return f
  1683. end
  1684. function Factory.CommonHoverTooltip(frame)
  1685.     frame:SetScript("OnEnter", CommonTooltip_OnEnter)
  1686.     frame:SetScript("OnLeave", HideOwnGameTooltip)
  1687.     return frame
  1688. end
  1689. function Factory.MissionBaseBackground(parent, expandW, expandH)
  1690.     local eX, eY, t = expandW or 10, expandH or expandW or 10
  1691.     t = parent:CreateTexture(nil, "BORDER")
  1692.     t:SetAtlas("Garr_InfoBoxMission-BackgroundTile")
  1693.     t:SetPoint("TOPLEFT", -eX, eY)
  1694.     t:SetPoint("BOTTOMRIGHT", eX, -eY)
  1695.     t = parent:CreateTexture(nil, "BORDER", nil, 1)
  1696.     parent["BaseFrameTop"] = t
  1697.     t:SetAtlas("_Garr_InfoBoxMission-Top", true)
  1698.     t:SetHorizTile(true)
  1699.     t:SetPoint("TOPLEFT", 1-eX, 7+eY)
  1700.     t:SetPoint("TOPRIGHT", -1+eX, 7+eY)
  1701.     t = parent:CreateTexture(nil, "BORDER", nil, 1)
  1702.     parent["BaseFrameBottom"] = t
  1703.     t:SetAtlas("_Garr_InfoBoxMission-Top", true)
  1704.     t:SetHorizTile(true)
  1705.     t:SetPoint("BOTTOMLEFT", -eX, -7-eY)
  1706.     t:SetPoint("BOTTOMRIGHT", eX, -7-eY)
  1707.     t:SetTexCoord(0.0, 1.0, 1.0, 0.0)
  1708.     t = parent:CreateTexture(nil, "BORDER", nil, 1)
  1709.     parent["BaseFrameLeft"] = t
  1710.     t:SetAtlas("!Garr_InfoBoxMission-Left", true)
  1711.     t:SetVertTile(true)
  1712.     t:SetPoint("TOPLEFT", -7-eX, eY)
  1713.     t:SetPoint("BOTTOMLEFT", -7-eX, -eY)
  1714.     t = parent:CreateTexture(nil, "BORDER", nil, 1)
  1715.     parent["BaseFrameRight"] = t
  1716.     t:SetAtlas("!Garr_InfoBoxMission-Left", true)
  1717.     t:SetVertTile(true)
  1718.     t:SetPoint("TOPRIGHT", 7+eX, eY)
  1719.     t:SetPoint("BOTTOMRIGHT", 7+eX, -eY)
  1720.     t:SetTexCoord(1.0, 0.0, 0.0, 1.0)
  1721.  
  1722.     t = parent:CreateTexture(nil, "BORDER", nil, 2)
  1723.     parent["BaseFrameTopLeft"] = t
  1724.     t:SetAtlas("Garr_InfoBoxMission-Corner", true)
  1725.     t:SetPoint("TOPLEFT", -6-eX, 7+eY)
  1726.     t = parent:CreateTexture(nil, "BORDER", nil, 2)
  1727.     parent["BaseFrameTopRight"] = t
  1728.     t:SetAtlas("Garr_InfoBoxMission-Corner", true)
  1729.     t:SetPoint("TOPRIGHT", 6+eX, 7+eY)
  1730.     t:SetTexCoord(1.0, 0.0, 0.0, 1.0)
  1731.     t = parent:CreateTexture(nil, "BORDER", nil, 2)
  1732.     parent["BaseFrameBottomLeft"] = t
  1733.     t:SetAtlas("Garr_InfoBoxMission-Corner", true)
  1734.     t:SetPoint("BOTTOMLEFT", -7-eX, -7-eY)
  1735.     t:SetTexCoord(0.0, 1.0, 1.0, 0.0)
  1736.     t = parent:CreateTexture(nil, "BORDER", nil, 2)
  1737.     parent["BaseFrameBottomRight"] = t
  1738.     t:SetAtlas("Garr_InfoBoxMission-Corner", true)
  1739.     t:SetPoint("BOTTOMRIGHT", 7+eX, -7-eY)
  1740.     t:SetTexCoord(1.0, 0.0, 1.0, 0.0)
  1741.  
  1742.     t = parent:CreateTexture(nil, "BORDER", nil, 4)
  1743.     t:SetAtlas("_Garr_InfoBoxBorderMission-Top", true)
  1744.     t:SetHorizTile(true)
  1745.     t:SetPoint("TOPLEFT", -eX,eY)
  1746.     t:SetPoint("TOPRIGHT", eX,eY)
  1747.     t = parent:CreateTexture(nil, "BORDER", nil, 4)
  1748.     t:SetAtlas("_Garr_InfoBoxBorderMission-Top", true)
  1749.     t:SetHorizTile(true)
  1750.     t:SetPoint("BOTTOMLEFT", -eX,-eY)
  1751.     t:SetPoint("BOTTOMRIGHT", eX,-eY)
  1752.     t:SetTexCoord(0.0, 1.0, 1.0, 0.0)
  1753.     t = parent:CreateTexture(nil, "BORDER", nil, 4)
  1754.     t:SetAtlas("!Garr_InfoBoxBorderMission-Left", true)
  1755.     t:SetVertTile(true)
  1756.     t:SetPoint("TOPLEFT", -eX,eY)
  1757.     t:SetPoint("BOTTOMLEFT", -eX,-eY)
  1758.     t = parent:CreateTexture(nil, "BORDER", nil, 4)
  1759.     t:SetAtlas("!Garr_InfoBoxBorderMission-Left", true)
  1760.     t:SetVertTile(true)
  1761.     t:SetPoint("TOPRIGHT", eX,eY)
  1762.     t:SetPoint("BOTTOMRIGHT", eX,-eY)
  1763.     t:SetTexCoord(1.0, 0.0, 0.0, 1.0)
  1764.  
  1765.     t = parent:CreateTexture(nil, "BORDER", nil, 5)
  1766.     t:SetAtlas("Garr_InfoBoxBorderMission-Corner", true)
  1767.     t:SetPoint("TOPLEFT", -eX, eY)
  1768.     t = parent:CreateTexture(nil, "BORDER", nil, 5)
  1769.     t:SetAtlas("Garr_InfoBoxBorderMission-Corner", true)
  1770.     t:SetPoint("TOPRIGHT", eX, eY)
  1771.     t:SetTexCoord(1.0, 0.0, 0.0, 1.0)
  1772.     t = parent:CreateTexture(nil, "BORDER", nil, 5)
  1773.     t:SetAtlas("Garr_InfoBoxBorderMission-Corner", true)
  1774.     t:SetPoint("BOTTOMLEFT", -eX, -eY)
  1775.     t:SetTexCoord(0.0, 1.0, 1.0, 0.0)
  1776.     t = parent:CreateTexture(nil, "BORDER", nil, 5)
  1777.     t:SetAtlas("Garr_InfoBoxBorderMission-Corner", true)
  1778.     t:SetPoint("BOTTOMRIGHT", eX, -eY)
  1779.     t:SetTexCoord(1.0, 0.0, 1.0, 0.0)
  1780. end
  1781. function Factory.CountdownText(widget, textWidget)
  1782.     widget.SetCountdown = CountdownText_SetCountdown
  1783.     widget.CDTDisplay = textWidget or widget
  1784. end
  1785. function Factory.AchievementRewardIcon(parent)
  1786.     local f, t = CreateObject("CommonHoverTooltip", CreateFrame("Button", nil, parent))
  1787.     f:SetSize(30,30)
  1788.     f:SetScript("OnHide", HideOwnGameTooltip)
  1789.     f:SetScript("OnClick", CommonLinkable_OnClick)
  1790.     t = f:CreateTexture(nil, "ARTWORK")
  1791.     t:SetTexture("Interface/AchievementFrame/UI-Achievement-Progressive-Shield")
  1792.     t:SetTexCoord(0, 0.75, 0, 0.75)
  1793.     t:SetAllPoints()
  1794.     return f
  1795. end
  1796. function Factory.ProgressBar(parent)
  1797.     local f, t, r = CreateFrame("Button", nil, parent)
  1798.     f:Disable()
  1799.     f:SetHeight(16)
  1800.     f:SetHitRectInsets(-3, -3, -6, -4)
  1801.     t = f:CreateTexture(nil, "BACKGROUND")
  1802.     t:SetAtlas("UI-Frame-Bar-BGLeft", true)
  1803.     t:SetPoint("LEFT", -2,0)
  1804.     t = f:CreateTexture(nil, "BACKGROUND")
  1805.     t:SetAtlas("UI-Frame-Bar-BGRight", true)
  1806.     t:SetPoint("RIGHT", 2,0)
  1807.     t = f:CreateTexture(nil, "BACKGROUND")
  1808.     t:SetAtlas("UI-Frame-Bar-BGCenter")
  1809.     t:SetPoint("LEFT", 27,0)
  1810.     t:SetPoint("RIGHT", -27,0)
  1811.     t:SetHeight(18)
  1812.     t = f:CreateTexture(nil, "BORDER")
  1813.     t:SetAtlas("UI-Frame-Bar-BorderLeft", true)
  1814.     t:SetPoint("LEFT", -8,0)
  1815.     t = f:CreateTexture(nil, "BORDER")
  1816.     t:SetAtlas("UI-Frame-Bar-BorderRight", true)
  1817.     t:SetPoint("RIGHT", 8,0)
  1818.     t = f:CreateTexture(nil, "BORDER")
  1819.     t:SetAtlas("UI-Frame-Bar-BorderCenter")
  1820.     t:SetPoint("LEFT", 27,0)
  1821.     t:SetPoint("RIGHT", -27,0)
  1822.     t:SetHeight(31)
  1823.     t, r = f:CreateTexture(nil, "HIGHLIGHT"), CreateObject("ObjectGroup")
  1824.     t:SetAtlas("UI-Frame-Bar-BorderLeft", true)
  1825.     t:SetPoint("LEFT", -8,0)
  1826.     t, r[#r+1] = f:CreateTexture(nil, "HIGHLIGHT"), t
  1827.     t:SetAtlas("UI-Frame-Bar-BorderRight", true)
  1828.     t:SetPoint("RIGHT", 8,0)
  1829.     t, r[#r+1] = f:CreateTexture(nil, "HIGHLIGHT", nil, 2), t
  1830.     t:SetAtlas("UI-Frame-Bar-BorderCenter")
  1831.     t:SetPoint("LEFT", 27,0)
  1832.     t:SetPoint("RIGHT", -27,0)
  1833.     t:SetHeight(31)
  1834.     r[#r+1], f.Highlight = t, r
  1835.     r:SetBlendMode("ADD")
  1836.     t = f:CreateTexture(nil, "BACKGROUND", nil, 2)
  1837.     t:SetAtlas("UI-Frame-Bar-Fill-Red")
  1838.     t:SetPoint("TOPLEFT")
  1839.     t:SetPoint("BOTTOMLEFT")
  1840.     t:SetWidth(50)
  1841.     f:SetText(" ")
  1842.     t, f.Fill = f:GetFontString(), t
  1843.     t:SetFontObject(GameFontHighlight)
  1844.     f:SetPushedTextOffset(-1, -1)
  1845.     t:SetPoint("TOPLEFT", 4, 0)
  1846.     t:SetPoint("BOTTOMRIGHT", -4, 1)
  1847.     t:SetJustifyV("MIDDLE")
  1848.     f.Text = t
  1849.     f.SetProgress = Progress_SetProgress
  1850.     f.SetProgressCountdown = Progress_SetTimer
  1851.     return f
  1852. end
  1853. function Factory.TooltipProgressBar()
  1854.     local f, t = CreateFrame("Frame")
  1855.     f:SetSize(180, 30)
  1856.     f:Hide()
  1857.     t = CreateObject("ProgressBar", f)
  1858.     t:SetPoint("LEFT", 8, 0)
  1859.     t:SetPoint("RIGHT", -8, 0)
  1860.     t:SetClipsChildren(true)
  1861.     t.Fill:SetAtlas("UI-Frame-Bar-Fill-Blue")
  1862.     t, f.Bar = t:CreateTexture(nil, "BACKGROUND", nil, 2), t
  1863.     t:SetAtlas("UI-Frame-Bar-Fill-Yellow")
  1864.     t:SetPoint("TOPLEFT", f.Bar.Fill, "TOPRIGHT")
  1865.     t:SetPoint("BOTTOMLEFT", f.Bar.Fill, "BOTTOMRIGHT")
  1866.     t:SetWidth(50)
  1867.     f.Activate, f.Fill2 = TooltipProgressBar_Activate, t
  1868.     f:SetScript("OnHide", TooltipProgressBar_OnHide)
  1869.     f:SetScript("OnUpdate", TooltipProgressBar_Update)
  1870.     return f
  1871. end
  1872. function Factory.ControlContainerBorder(parent, expandX, expandY)
  1873.     expandX, expandY = expandX or 0, expandY or 0
  1874.     local t, is, ts = parent:CreateTexture(nil, "BACKGROUND"), 18, 1/16
  1875.     t:SetAtlas("adventures_mission_materialframe")
  1876.     t:SetTexCoord(0, ts, 0, 1)
  1877.     t:SetPoint("TOPLEFT", -expandX, expandY)
  1878.     t:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", is-expandX, -expandY)
  1879.     t = parent:CreateTexture(nil, "BACKGROUND")
  1880.     t:SetTexCoord(ts, 1-ts, 0, 1)
  1881.     t:SetAtlas("adventures_mission_materialframe")
  1882.     t:SetPoint("TOPLEFT", is-expandX, expandY)
  1883.     t:SetPoint("BOTTOMRIGHT", -is+expandX, -expandY)
  1884.     t = parent:CreateTexture(nil, "BACKGROUND")
  1885.     t:SetTexCoord(1-ts, 1, 0, 1)
  1886.     t:SetAtlas("adventures_mission_materialframe")
  1887.     t:SetPoint("TOPRIGHT", expandX, expandY)
  1888.     t:SetPoint("BOTTOMLEFT", parent, "BOTTOMRIGHT", -is+expandX, -expandY)
  1889. end
  1890. function Factory.ILButton(parent)
  1891.     local f = CreateObject("CommonHoverTooltip", CreateFrame("Button", nil, parent))
  1892.     f:SetSize(60, 23)
  1893.     f.tooltipAnchor, f.tooltipYO = "ANCHOR_BOTTOM", -6
  1894.     local t = f:CreateTexture()
  1895.     t:SetSize(18, 18)
  1896.     t:SetTexture("Interface/Icons/Temp")
  1897.     t:SetTexCoord(4/64,60/64, 4/64,60/64)
  1898.     t:SetPoint("LEFT", 1, 0)
  1899.     t, f.Icon = f:CreateFontString(nil, "OVERLAY", "GameFontHighlightMed2"), t
  1900.     t:SetPoint("LEFT", 25, 0)
  1901.     f.SetText, f.Text = ResizedButton_SetText, t
  1902.     f:SetText("00")
  1903.     CreateObject("ControlContainerBorder", f, 15, 9)
  1904.     return f
  1905. end
  1906. function Factory.ResourceButton(parent, currencyID)
  1907.     local f = CreateObject("ILButton", parent)
  1908.     f.currencyID = currencyID
  1909.     f:RegisterEvent("CURRENCY_DISPLAY_UPDATE")
  1910.     f:SetScript("OnEvent", ResourceButton_Update)
  1911.     f:SetScript("OnClick", ResourceButton_OnClick)
  1912.     local ci = C_CurrencyInfo.GetCurrencyInfo(currencyID)
  1913.     f.Icon:SetTexture(ci and ci.iconFileID or "Interface/Icons/Temp")
  1914.     ResourceButton_Update(f, nil, currencyID)
  1915.     return f
  1916. end
  1917. function Factory.FollowerListButton(parent, isTroop)
  1918.     local f,t = CreateFrame("Button", nil, parent)
  1919.     local s = CreateObject("Shadow", f)
  1920.     local f2 = CreateFrame("Frame", nil, f)
  1921.     local ett = {}
  1922.     f2:SetAllPoints()
  1923.     f:RegisterForClicks("LeftButtonUp", "RightButtonUp")
  1924.     f:RegisterForDrag("LeftButton")
  1925.     f:SetMotionScriptsWhileDisabled(true)
  1926.     f:SetHitRectInsets(-3,4,0,5)
  1927.     f:SetScript("OnDragStart", FollowerButton_OnDragStart)
  1928.     f:SetScript("OnDragStop", FollowerButton_OnDragStop)
  1929.     f:SetScript("OnClick", FollowerButton_OnClick)
  1930.     f:SetScript("OnEnter", FollowerButton_OnEnter)
  1931.     f:SetScript("OnLeave", HideOwnGameTooltip)
  1932.     f:SetSize(70, 70)
  1933.     t = f:CreateTexture(nil, "BORDER")
  1934.     t:SetAtlas(isTroop and "adventurers-followers-frame-troops" or "adventurers-followers-frame")
  1935.     t:SetSize(60, 60)
  1936.     t:SetPoint("CENTER", 0, 5)
  1937.     t, s.PortraitR = f:CreateTexture(nil, "BORDER", nil, 2), t
  1938.     t:SetAtlas("adventurers-followers-xp")
  1939.     t:SetVertexColor(1, 0.35, 0)
  1940.     t:SetSize(50, 51)
  1941.     t:SetPoint("CENTER", 0, 5)
  1942.     t, s.PortraitT = f:CreateTexture(nil, "BACKGROUND", nil, 1), t
  1943.     t:SetSize(46, 46)
  1944.     t:SetPoint("CENTER", 0, 5)
  1945.     t:SetTexture(1605024)
  1946.     t:SetDesaturated(true)
  1947.     t:SetBlendMode("ADD")
  1948.     t:SetAlpha(0.5)
  1949.     t, s.Portrait2 = f:CreateTexture(nil, "BACKGROUND"), t
  1950.     t:SetSize(46, 46)
  1951.     t:SetPoint("CENTER", 0, 5)
  1952.     t:SetTexture(1605024)
  1953.     t, s.Portrait = f2:CreateTexture(nil, "ARTWORK", nil, -1), t
  1954.     t:SetColorTexture(1,1,1)
  1955.     t:SetGradient("VERTICAL", 0.15,0.15,0.15, 0.2,0.2, 0.2)
  1956.     t:SetSize(39, 12)
  1957.     t:SetPoint("BOTTOMRIGHT", -9, 10)
  1958.     t, s.HealthBG = f2:CreateTexture(nil, "ARTWORK"), t
  1959.     t:SetColorTexture(1,1,1)
  1960.     t:SetGradient("VERTICAL", 0.10,0.25,0.10, 0.05,0.5,0.05)
  1961.     t:SetAlpha(0.85)
  1962.     t:SetSize(24, s.HealthBG:GetHeight())
  1963.     t:SetPoint("BOTTOMLEFT", s.HealthBG, "BOTTOMLEFT")
  1964.     t, s.Health = f2:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall"), t
  1965.     t:SetPoint("BOTTOMLEFT", f, "BOTTOM", -6, 11)
  1966.     t, s.TextLabel = f2:CreateTexture(nil, "ARTWORK", nil, 4), t
  1967.     t:SetSize(14,16)
  1968.     t:SetAtlas("bags-greenarrow")
  1969.     t:SetPoint("BOTTOMRIGHT", -8, 7.5)
  1970.     t:Hide()
  1971.     s.Blip = t
  1972.     t = f2:CreateTexture(nil, "ARTWORK", nil, 4)
  1973.     t:SetAtlas("adventure-healthbar")
  1974.     t:SetPoint("BOTTOMRIGHT", -5, -5)
  1975.     t:SetTexCoord(30/89, 1, 0, 1)
  1976.     t:SetSize(48, 36)
  1977.     s.HealthFrameR = t
  1978.     t = f2:CreateTexture(nil, "ARTWORK", nil, 5)
  1979.     t:SetAtlas("adventures-tank")
  1980.     t:SetSize(20.53,22)
  1981.     t:SetPoint("BOTTOMLEFT", 4, 5)
  1982.     s.Role = t
  1983.     t = f2:CreateTexture(nil, "ARTWORK", nil, 6)
  1984.     t:SetAtlas("adventure_ability_frame")
  1985.     t:SetSize(26.72, 26)
  1986.     t:SetPoint("CENTER", s.Role, "CENTER", 0, -2)
  1987.     t, s.RoleB, ett[#ett+1] = f2:CreateTexture(nil, "ARTWORK", nil, 6), t, t
  1988.     t:SetPoint("TOPRIGHT", 0, 2)
  1989.     t:SetSize(24,25)
  1990.     t:SetAtlas("collections-icon-favorites")
  1991.     s.Favorite, s.Abilities, s.AbilitiesB = t, {}, {}
  1992.     for i=1,2 do
  1993.         t = f2:CreateTexture(nil, "ARTWORK", nil, 3)
  1994.         t:SetAtlas("adventure_ability_frame")
  1995.         t:SetSize(26.72, 26)
  1996.         t:SetPoint("CENTER", s.Portrait, "CENTER", cos(232-i*42)*30, sin(232-i*42)*30)
  1997.         t, ett[#ett+1], s.AbilitiesB[i] = f2:CreateTexture(nil, "ARTWORK", nil, 2), t, t
  1998.         t:SetSize(17, 17)
  1999.         t:SetPoint("CENTER", s.AbilitiesB[i], "CENTER", 0, 1)
  2000.         t:SetTexture("Interface/Icons/Temp")
  2001.         t:SetMask("Interface/Masks/CircleMaskScalable")
  2002.         s.Abilities[i] = t
  2003.     end
  2004.     ett[#ett+1] = s.HealthFrameR
  2005.     t = f:CreateTexture(nil, "HIGHLIGHT")
  2006.     t:SetTexture("Interface/Common/CommonRoundHighlight")
  2007.     t:SetTexCoord(0,58/64,0,58/64)
  2008.     t:SetPoint("TOPLEFT", s.Portrait, "TOPLEFT", -1, 1)
  2009.     t:SetPoint("BOTTOMRIGHT", s.Portrait, "BOTTOMRIGHT", 1,-1)
  2010.     s.Hi = t
  2011.     if not isTroop then
  2012.         t = f:CreateTexture(nil, "BORDER", nil, -1)
  2013.         t:SetAtlas("adventures-buff-heal-ring")
  2014.         local divC = CovenKit == "Kyrian" and 0x78c7ff or CovenKit == "Venthyr" and 0xcf1500 or CovenKit == "Necrolord" and 0x76c900 or 0x0058e6
  2015.         t:SetVertexColor(divC / 2^24, divC/256 % 256 / 255, divC%256/255)
  2016.         t:SetPoint("TOPLEFT", s.PortraitR, "TOPLEFT", -6, 6)
  2017.         t:SetPoint("BOTTOMRIGHT", s.PortraitR, "BOTTOMRIGHT", 6, -6)
  2018.         s.EC = t
  2019.     end
  2020.     s.ExtraTex = CreateObject("ObjectGroup", ett)
  2021.     f.GetInfo = FollowerButton_GetInfo
  2022.     f.GetFollowerGUID = FollowerButton_GetFollowerGUID
  2023.     return f
  2024. end
  2025. function Factory.FollowerList(parent)
  2026.     local f,t = CreateFrame("Frame", nil, parent)
  2027.     local s = CreateObject("Shadow", f)
  2028.     f:SetSize(320, 370)
  2029.     t = f:CreateTexture(nil, "BACKGROUND")
  2030.     t:SetAllPoints()
  2031.     t:SetAtlas("adventures-followers-bg")
  2032.     t = f:CreateTexture(nil, "BORDER")
  2033.     t:SetPoint("TOPLEFT")
  2034.     t:SetSize(320, 84)
  2035.     t:SetAtlas("adventures-followers-frame")
  2036.     t:SetTexCoord(0,1, 0, 50/311)
  2037.     t = f:CreateTexture(nil, "BORDER")
  2038.     t:SetPoint("BOTTOMLEFT")
  2039.     t:SetSize(320, 84)
  2040.     t:SetAtlas("adventures-followers-frame")
  2041.     t:SetTexCoord(0,1, 261/311,1)
  2042.     t = f:CreateTexture(nil, "BORDER")
  2043.     t:SetAtlas("adventures-followers-frame")
  2044.     t:SetPoint("TOPLEFT", 0, -84)
  2045.     t:SetPoint("BOTTOMRIGHT", 0, 84)
  2046.     t:SetTexCoord(0,1,50/311,261/311)
  2047.  
  2048.     t = f:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
  2049.     --t:SetText(FOLLOWERLIST_LABEL_TROOPS)
  2050.     t:SetPoint("TOPLEFT", 12, -20)
  2051.     s.troops = {}
  2052.     for i=1,2 do
  2053.         s.troops[i] = CreateObject("FollowerListButton", f, true)
  2054.         s.troops[i]:SetPoint("TOPLEFT", (i-1)*68+14, -20)
  2055.     end
  2056.     t = CreateObject("CommonHoverTooltip", CreateObject("InfoButton", f))
  2057.     t:SetPoint("TOPRIGHT", -12, -20)
  2058.     t.tooltipHeader = FOLLOWERLIST_LABEL_TROOPS
  2059.     t.tooltipText = COVENANT_MISSIONS_TUTORIAL_TROOPS
  2060.     s.TroopInfo = t
  2061.  
  2062.     t = f:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
  2063.     --t:SetText(COVENANT_MISSION_FOLLOWER_CATEGORY)
  2064.     t:SetPoint("TOPLEFT", 12, -110)
  2065.     s.companions = {}
  2066.     for i=1,#C_Garrison.GetFollowers(123) do
  2067.         t = CreateObject("FollowerListButton", f, false)
  2068.         t:SetPoint("TOPLEFT", ((i-1)%4)*74+14, -math.floor((i-1)/4)*64-110)
  2069.         s.companions[i] = t
  2070.     end
  2071.     f:SetPoint("LEFT", UIParent, "LEFT", 20, 0)
  2072.  
  2073.     f.Refresh = FollowerList_Refresh
  2074.     f.SyncToBoard = FollowerList_SyncToBoard
  2075.     f.SyncXPGain = FollowerList_SyncXPGain
  2076.     f:SetScript("OnUpdate", FollowerList_OnUpdate)
  2077.     f:SetScript("OnShow", FollowerList_Refresh)
  2078.     f:Hide()
  2079.     return f
  2080. end
  2081. function Factory.InfoButton(parent)
  2082.     local f = CreateFrame("Button", nil, parent)
  2083.     f:SetSize(20, 20)
  2084.     f:SetNormalTexture("Interface/Common/Help-i")
  2085.     f:GetNormalTexture():SetTexCoord(0.2, 0.8, 0.2, 0.8)
  2086.     f:SetHighlightTexture("Interface/Common/Help-i")
  2087.     f:GetHighlightTexture():SetTexCoord(0.2, 0.8, 0.2, 0.8)
  2088.     f:GetHighlightTexture():SetBlendMode("ADD")
  2089.     f:GetHighlightTexture():SetAlpha(0.25)
  2090.     return f
  2091. end
  2092. function Factory.TexSlice(parent, layer,subLevel, tex,tW,tH, x0,x1,x2,x3, y0,y1,y2,y3, xS,yS, oT,oR,oB,oL, mL)
  2093.     local r, ni, t = CreateObject("ObjectGroup"), 1
  2094.     for i=1,yS == 0 and 3 or 9 do
  2095.         r[i] = parent:CreateTexture(nil, layer, nil, subLevel)
  2096.     end
  2097.     r:SetTexture(tex)
  2098.  
  2099.     x0,x1,x2,x3=x0/tW,x1/tW,x2/tW,x3/tW
  2100.     y0,y1,y2,y3=y0/tH,y1/tH,y2/tH,y3/tH
  2101.     if yS > 0 then
  2102.         t, ni = r[ni], ni + 1
  2103.         t:SetTexCoord(mL and x3 or x0, mL and x2 or x1, y0, y1)
  2104.         t:SetPoint("TOPLEFT", -oL, oT)
  2105.         t:SetSize(xS, yS)
  2106.         t, ni = r[ni], ni + 1
  2107.         t:SetTexCoord(x1, x2, y0, y1)
  2108.         t:SetPoint("TOPLEFT", xS-oL, oT)
  2109.         t:SetPoint("BOTTOMRIGHT", parent, "TOPRIGHT", oR-xS, oT-yS)
  2110.         t, ni = r[ni], ni + 1
  2111.         t:SetTexCoord(x2, x3, y0, y1)
  2112.         t:SetPoint("TOPRIGHT", oR, oT)
  2113.         t:SetSize(xS, yS)
  2114.     end
  2115.     t, ni = r[ni], ni + 1
  2116.     t:SetTexCoord(mL and x3 or x0, mL and x2 or x1, y1, y2)
  2117.     t:SetPoint("TOPLEFT", -oL, oT-yS)
  2118.     t:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", xS-oL, yS-oB)
  2119.     t, ni = r[ni], ni + 1
  2120.     t:SetTexCoord(x1, x2, y1, y2)
  2121.     t:SetPoint("TOPLEFT", xS-oL, oT-yS)
  2122.     t:SetPoint("BOTTOMRIGHT", -xS+oR, yS-oB)
  2123.     t, ni = r[ni], ni + 1
  2124.     t:SetTexCoord(x2, x3, y1, y2)
  2125.     t:SetPoint("TOPLEFT", parent, "TOPRIGHT", oR-xS, oT-yS)
  2126.     t:SetPoint("BOTTOMRIGHT", oR, yS-oB)
  2127.     if yS > 0 then
  2128.         t, ni = r[ni], ni + 1
  2129.         t:SetTexCoord(mL and x3 or x0, mL and x2 or x1, y2, y3)
  2130.         t:SetPoint("BOTTOMLEFT", -oL, -oB)
  2131.         t:SetSize(xS, yS)
  2132.         t, ni = r[ni], ni + 1
  2133.         t:SetTexCoord(x1, x2, y2, y3)
  2134.         t:SetPoint("BOTTOMLEFT", -oL+xS, -oB)
  2135.         t:SetPoint("TOPRIGHT", parent, "BOTTOMRIGHT", oR-xS, yS-oB)
  2136.         t, ni = r[ni], ni + 1
  2137.         t:SetTexCoord(x2, x3, y2, y3)
  2138.         t:SetPoint("BOTTOMRIGHT", oR, -oB)
  2139.         t:SetSize(xS, yS)
  2140.     end
  2141.  
  2142.     return r
  2143. end
  2144. function Factory.MissionToast(parent)
  2145.     local f, t = CreateFrame("Button", nil, parent)
  2146.     local sf = CreateObject("Shadow", f)
  2147.     f:SetSize(295, 40)
  2148.     f:SetFrameStrata("FULLSCREEN")
  2149.     f:SetHitRectInsets(-6, -6, -6, -6)
  2150.     f:RegisterForClicks("RightButtonUp")
  2151.     f:SetScript("OnUpdate", Toast_Animate)
  2152.     f:SetScript("OnClick", Toast_OnClick)
  2153.     f.Background = CreateObject("TexSlice", f, "BACKGROUND", 0, "Interface/LootFrame/LootToast",1024,256, 578,638,763,823, 0,3,69,0, 45,0, 5,0,5,0, true)
  2154.     t = f:CreateTexture(nil, "ARTWORK")
  2155.     t:SetAtlas("loottoast-sheen")
  2156.     t:SetBlendMode("ADD")
  2157.     t:SetSize(90, 38) -- 171,75
  2158.     t:SetPoint("LEFT", 20, -1)
  2159.     t, f.Sheen = f:CreateTexture(nil, "OVERLAY", nil, -2), t
  2160.     t:SetTexture("Interface/AchievementFrame/UI-Achievement-Alert-Glow")
  2161.     t:SetTexCoord(5/512, 395/512, 5/256, 167/256)
  2162.     t:SetPoint("BOTTOMLEFT", -35, -30)
  2163.     t:SetPoint("TOPRIGHT", 35, 30)
  2164.     t:SetBlendMode("ADD")
  2165.     t, f.PreGlow = CreateObject("RewardBlock", f, 32, 2), t
  2166.     t.Container:SetPoint("LEFT", 10, -1)
  2167.     for i=1,3 do
  2168.         local ti = t[i]
  2169.         ti.tooltipAnchor, ti.tooltipXO, ti.tooltipFXO = "ANCHOR_TRUE_LEFT", -34*i+28, 285-34*i
  2170.         ti.tooltipPostShow = MissionToast_CheckTooltip
  2171.         ti.isRetrospective, ti.ShowQuantityFromWidgetText = true, "Quantity"
  2172.         ti.Quantity:Hide()
  2173.     end
  2174.     t, sf.Rewards = f:CreateFontString(nil, "ARTWORK", "GameFontNormal"), t
  2175.     t:SetPoint("TOPLEFT", sf.Rewards.Container, "TOPRIGHT", 2, -2.25)
  2176.     t:SetPoint("TOPRIGHT", -10, -7)
  2177.     t:SetHeight(12)
  2178.     t:SetText("|cffff8000Legendary Mission")
  2179.     t, f.Header = f:CreateFontString(nil, "ARTWORK", "GameFontHighlight"), t
  2180.     t:SetPoint("BOTTOMLEFT", sf.Rewards.Container, "BOTTOMRIGHT", 2, 2.25)
  2181.     t:SetPoint("BOTTOMRIGHT", -10, 7)
  2182.     t:SetHeight(12)
  2183.     t:SetText("Legendary Goat Rescue")
  2184.     t, f.Detail = f:CreateTexture(nil, "ARTWORK", nil, 0), t
  2185.     t:SetSize(28, 28)
  2186.     t:SetPoint("LEFT", 12, -1)
  2187.     t:SetTexture(1605024)
  2188.     t, f.Portrait = f:CreateTexture(nil, "ARTWORK", nil, 1), t
  2189.     t:SetSize(34,34)
  2190.     t:SetAtlas("adventurers-followers-frame")
  2191.     t:SetPoint("CENTER", f.Portrait, "CENTER")
  2192.     f.PortraitFrame = t
  2193.  
  2194.     f:Hide()
  2195.     return f
  2196. end
  2197. function Factory.IconButton(parent, sz, tex)
  2198.     local mb = CreateFrame("Button", nil, parent)
  2199.     mb:SetSize(sz, sz)
  2200.     mb:SetNormalTexture(tex or "Interface/Icons/Temp")
  2201.     mb:SetHighlightTexture("Interface/Buttons/ButtonHilight-Square")
  2202.     mb:GetHighlightTexture():SetBlendMode("ADD")
  2203.     mb:SetPushedTexture("Interface/Buttons/UI-Quickslot-Depress")
  2204.     mb:GetPushedTexture():SetDrawLayer("OVERLAY")
  2205.     local t = mb:CreateTexture(nil, "ARTWORK")
  2206.     t:SetAllPoints()
  2207.     t:SetTexture(tex or "Interface/Icons/Temp")
  2208.     mb.Icon = t
  2209.     return mb
  2210. end
  2211. function Factory.SharedTooltipProgressBar()
  2212.     tooltipSharedPB = tooltipSharedPB or CreateObject("TooltipProgressBar")
  2213.     return tooltipSharedPB
  2214. end
  2215. function Factory.Shadow(t)
  2216.     if t ~= nil then
  2217.         local s = S[t] or {}
  2218.         S[t], S[s] = s, t
  2219.         return s
  2220.     end
  2221. end
  2222.  
RAW Paste Data