stoneharry

Untitled

Mar 7th, 2014
403
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 36.45 KB | None | 0 0
  1.  
  2. StaticPopupDialogs["CONFIRM_LEARN_PREVIEW_TALENTS"] = {
  3.     text = CONFIRM_LEARN_PREVIEW_TALENTS,
  4.     button1 = YES,
  5.     button2 = NO,
  6.     OnAccept = function (self)
  7.         LearnPreviewTalents(PlayerTalentFrame.pet);
  8.     end,
  9.     OnCancel = function (self)
  10.     end,
  11.     hideOnEscape = 1,
  12.     timeout = 0,
  13.     exclusive = 1,
  14. }
  15.  
  16. UIPanelWindows["PlayerTalentFrame"] = { area = "left", pushable = 6, whileDead = 1 };
  17.  
  18.  
  19. -- global constants
  20. GLYPH_TALENT_TAB = 4;
  21.  
  22.  
  23. -- speed references
  24. local next = next;
  25. local ipairs = ipairs;
  26.  
  27. -- local data
  28. local specs = {
  29.     ["spec1"] = {
  30.         name = TALENT_SPEC_PRIMARY,
  31.         talentGroup = 1,
  32.         unit = "player",
  33.         pet = false,
  34.         tooltip = TALENT_SPEC_PRIMARY,
  35.         portraitUnit = "player",
  36.         defaultSpecTexture = "Interface\\Icons\\Ability_Marksmanship",
  37.         hasGlyphs = true,
  38.         glyphName = TALENT_SPEC_PRIMARY_GLYPH,
  39.     },
  40.     ["spec2"] = {
  41.         name = TALENT_SPEC_SECONDARY,
  42.         talentGroup = 2,
  43.         unit = "player",
  44.         pet = false,
  45.         tooltip = TALENT_SPEC_SECONDARY,
  46.         portraitUnit = "player",
  47.         defaultSpecTexture = "Interface\\Icons\\Ability_Marksmanship",
  48.         hasGlyphs = true,
  49.         glyphName = TALENT_SPEC_SECONDARY_GLYPH,
  50.     },
  51.     ["petspec1"] = {
  52.         name = TALENT_SPEC_PET_PRIMARY,
  53.         talentGroup = 1,
  54.         unit = "pet",
  55.         tooltip = TALENT_SPEC_PET_PRIMARY,
  56.         pet = true,
  57.         portraitUnit = "pet",
  58.         defaultSpecTexture = nil,
  59.         hasGlyphs = false,
  60.         glyphName = nil,
  61.     },
  62. };
  63.  
  64. local specTabs = { };   -- filled in by PlayerSpecTab_OnLoad
  65. local numSpecTabs = 0;
  66. local selectedSpec = nil;
  67. local activeSpec = nil;
  68.  
  69.  
  70. -- cache talent info so we can quickly display cool stuff like the number of points spent in each tab
  71. local talentSpecInfoCache = {
  72.     ["spec1"]       = { },
  73.     ["spec2"]       = { },
  74.     ["petspec1"]    = { },
  75. };
  76. -- cache talent tab widths so we can resize tabs to fit for localization
  77. local talentTabWidthCache = { };
  78.  
  79.  
  80.  
  81. -- ACTIVESPEC_DISPLAYTYPE values:
  82. -- "BLUE", "GOLD_INSIDE", "GOLD_BACKGROUND"
  83. local ACTIVESPEC_DISPLAYTYPE = nil;
  84.  
  85. -- SELECTEDSPEC_DISPLAYTYPE values:
  86. -- "BLUE", "GOLD_INSIDE", "PUSHED_OUT", "PUSHED_OUT_CHECKED"
  87. local SELECTEDSPEC_DISPLAYTYPE = "GOLD_INSIDE";
  88. local SELECTEDSPEC_OFFSETX;
  89. if ( SELECTEDSPEC_DISPLAYTYPE == "PUSHED_OUT" or SELECTEDSPEC_DISPLAYTYPE == "PUSHED_OUT_CHECKED" ) then
  90.     SELECTEDSPEC_OFFSETX = 5;
  91. else
  92.     SELECTEDSPEC_OFFSETX = 0;
  93. end
  94.  
  95.  
  96. -- PlayerTalentFrame
  97.  
  98. function PlayerTalentFrame_Toggle(pet, suggestedTalentGroup)
  99.     local hidden;
  100.     local talentTabSelected = PanelTemplates_GetSelectedTab(PlayerTalentFrame) ~= GLYPH_TALENT_TAB;
  101.     if ( not PlayerTalentFrame:IsShown() ) then
  102.         ShowUIPanel(PlayerTalentFrame);
  103.         hidden = false;
  104.     else
  105.         local spec = selectedSpec and specs[selectedSpec];
  106.         if ( spec and talentTabSelected ) then
  107.             -- if a talent tab is selected then toggle the frame off
  108.             HideUIPanel(PlayerTalentFrame);
  109.             hidden = true;
  110.         else
  111.             hidden = false;
  112.         end
  113.     end
  114.     if ( not hidden ) then
  115.         -- open the spec with the requested talent group (or the current talent group if the selected
  116.         -- spec has one)
  117.         if ( selectedSpec ) then
  118.             local spec = specs[selectedSpec];
  119.             if ( spec.pet == pet ) then
  120.                 suggestedTalentGroup = spec.talentGroup;
  121.             end
  122.         end
  123.         for _, index in ipairs(TALENT_SORT_ORDER) do
  124.             local spec = specs[index];
  125.             if ( spec.pet == pet and spec.talentGroup == suggestedTalentGroup ) then
  126.                 PlayerSpecTab_OnClick(specTabs[index]);
  127.                 if ( not talentTabSelected ) then
  128.                     PlayerTalentTab_OnClick(_G["PlayerTalentFrameTab"..PlayerTalentTab_GetBestDefaultTab(index)]);
  129.                 end
  130.                 break;
  131.             end
  132.         end
  133.     end
  134. end
  135.  
  136. function PlayerTalentFrame_Open(pet, talentGroup)
  137.     ShowUIPanel(PlayerTalentFrame);
  138.     -- open the spec with the requested talent group
  139.     for index, spec in next, specs do
  140.         if ( spec.pet == pet and spec.talentGroup == talentGroup ) then
  141.             PlayerSpecTab_OnClick(specTabs[index]);
  142.             break;
  143.         end
  144.     end
  145. end
  146.  
  147. function PlayerTalentFrame_ToggleGlyphFrame(suggestedTalentGroup)
  148.     GlyphFrame_LoadUI();
  149.     if ( GlyphFrame ) then
  150.         local hidden;
  151.         if ( not PlayerTalentFrame:IsShown() ) then
  152.             ShowUIPanel(PlayerTalentFrame);
  153.             hidden = false;
  154.         else
  155.             local spec = selectedSpec and specs[selectedSpec];
  156.             if ( spec and spec.hasGlyphs and
  157.                  PanelTemplates_GetSelectedTab(PlayerTalentFrame) == GLYPH_TALENT_TAB ) then
  158.                 -- if the glyph tab is selected then toggle the frame off
  159.                 HideUIPanel(PlayerTalentFrame);
  160.                 hidden = true;
  161.             else
  162.                 hidden = false;
  163.             end
  164.         end
  165.         if ( not hidden ) then
  166.             -- open the spec with the requested talent group (or the current talent group if the selected
  167.             -- spec has one)
  168.             if ( selectedSpec ) then
  169.                 local spec = specs[selectedSpec];
  170.                 if ( spec.hasGlyphs ) then
  171.                     suggestedTalentGroup = spec.talentGroup;
  172.                 end
  173.             end
  174.             for _, index in ipairs(TALENT_SORT_ORDER) do
  175.                 local spec = specs[index];
  176.                 if ( spec.hasGlyphs and spec.talentGroup == suggestedTalentGroup ) then
  177.                     PlayerSpecTab_OnClick(specTabs[index]);
  178.                     PlayerTalentTab_OnClick(_G["PlayerTalentFrameTab"..GLYPH_TALENT_TAB]);
  179.                     break;
  180.                 end
  181.             end
  182.         end
  183.     end
  184. end
  185.  
  186. function PlayerTalentFrame_OpenGlyphFrame(talentGroup)
  187.     GlyphFrame_LoadUI();
  188.     if ( GlyphFrame ) then
  189.         ShowUIPanel(PlayerTalentFrame);
  190.         -- open the spec with the requested talent group
  191.         for index, spec in next, specs do
  192.             if ( spec.hasGlyphs and spec.talentGroup == talentGroup ) then
  193.                 PlayerSpecTab_OnClick(specTabs[index]);
  194.                 PlayerTalentTab_OnClick(_G["PlayerTalentFrameTab"..GLYPH_TALENT_TAB]);
  195.                 break;
  196.             end
  197.         end
  198.     end
  199. end
  200.  
  201. function PlayerTalentFrame_ShowGlyphFrame()
  202.     GlyphFrame_LoadUI();
  203.     if ( GlyphFrame ) then
  204.         -- set the title text of the GlyphFrame
  205.         if ( selectedSpec and specs[selectedSpec].glyphName and GetNumTalentGroups() > 1 ) then
  206.             GlyphFrameTitleText:SetText(specs[selectedSpec].glyphName);
  207.         else
  208.             GlyphFrameTitleText:SetText(GLYPHS);
  209.         end
  210.         -- show/update the glyph frame
  211.         if ( GlyphFrame:IsShown() ) then
  212.             GlyphFrame_Update();
  213.         else
  214.             GlyphFrame:Show();
  215.         end
  216.         -- don't forget to hide the scroll button overlay or it may show up on top of the GlyphFrame!
  217.         UIFrameFlashStop(PlayerTalentFrameScrollButtonOverlay);
  218.     end
  219. end
  220.  
  221. function PlayerTalentFrame_HideGlyphFrame()
  222.     if ( not GlyphFrame or not GlyphFrame:IsShown() ) then
  223.         return;
  224.     end
  225.  
  226.     GlyphFrame_LoadUI();
  227.     if ( GlyphFrame ) then
  228.         GlyphFrame:Hide();
  229.     end
  230. end
  231.  
  232.  
  233. function PlayerTalentFrame_OnLoad(self)
  234.     self:RegisterEvent("ADDON_LOADED");
  235.     self:RegisterEvent("PREVIEW_TALENT_POINTS_CHANGED");
  236.     self:RegisterEvent("PREVIEW_PET_TALENT_POINTS_CHANGED");
  237.     self:RegisterEvent("UNIT_PORTRAIT_UPDATE");
  238.     self:RegisterEvent("UNIT_PET");
  239.     self:RegisterEvent("PLAYER_LEVEL_UP");
  240.     self:RegisterEvent("PLAYER_TALENT_UPDATE");
  241.     self:RegisterEvent("PET_TALENT_UPDATE");
  242.     self:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED");
  243.     self.unit = "player";
  244.     self.inspect = false;
  245.     self.pet = false;
  246.     self.talentGroup = 1;
  247.     self.updateFunction = PlayerTalentFrame_Update;
  248.  
  249.     TalentFrame_Load(self);
  250.  
  251.     -- setup talent buttons
  252.     local button;
  253.     for i = 1, MAX_NUM_TALENTS do
  254.         button = _G["PlayerTalentFrameTalent"..i];
  255.         if ( button ) then
  256.             button:SetScript("OnClick", PlayerTalentFrameTalent_OnClick);
  257.             button:SetScript("OnEvent", PlayerTalentFrameTalent_OnEvent);
  258.             button:SetScript("OnEnter", PlayerTalentFrameTalent_OnEnter);
  259.         end
  260.     end
  261.  
  262.     -- setup tabs
  263.     PanelTemplates_SetNumTabs(self, MAX_TALENT_TABS + 1);   -- add one for the GLYPH_TALENT_TAB
  264.  
  265.     -- initialize active spec as a fail safe
  266.     local activeTalentGroup = GetActiveTalentGroup();
  267.     local numTalentGroups = GetNumTalentGroups();
  268.     PlayerTalentFrame_UpdateActiveSpec(activeTalentGroup, numTalentGroups);
  269.  
  270.     -- setup active spec highlight
  271.     if ( ACTIVESPEC_DISPLAYTYPE == "BLUE" ) then
  272.         PlayerTalentFrameActiveSpecTabHighlight:SetDrawLayer("OVERLAY");
  273.         PlayerTalentFrameActiveSpecTabHighlight:SetBlendMode("ADD");
  274.         PlayerTalentFrameActiveSpecTabHighlight:SetTexture("Interface\\Buttons\\UI-Button-Outline");
  275.     elseif ( ACTIVESPEC_DISPLAYTYPE == "GOLD_INSIDE" ) then
  276.         PlayerTalentFrameActiveSpecTabHighlight:SetDrawLayer("OVERLAY");
  277.         PlayerTalentFrameActiveSpecTabHighlight:SetBlendMode("ADD");
  278.         PlayerTalentFrameActiveSpecTabHighlight:SetTexture("Interface\\Buttons\\CheckButtonHilight");
  279.     elseif ( ACTIVESPEC_DISPLAYTYPE == "GOLD_BACKGROUND" ) then
  280.         PlayerTalentFrameActiveSpecTabHighlight:SetDrawLayer("BACKGROUND");
  281.         PlayerTalentFrameActiveSpecTabHighlight:SetWidth(74);
  282.         PlayerTalentFrameActiveSpecTabHighlight:SetHeight(86);
  283.         PlayerTalentFrameActiveSpecTabHighlight:SetTexture("Interface\\SpellBook\\SpellBook-SkillLineTab-Glow");
  284.     end
  285. end
  286.  
  287. function PlayerTalentFrame_OnShow(self)
  288.     -- Stop buttons from flashing after skill up
  289.     SetButtonPulse(TalentMicroButton, 0, 1);
  290.  
  291.     PlaySound("TalentScreenOpen");
  292.     UpdateMicroButtons();
  293.  
  294.     if ( not selectedSpec ) then
  295.         -- if no spec was selected, try to select the active one
  296.         PlayerSpecTab_OnClick(activeSpec and specTabs[activeSpec] or specTabs[DEFAULT_TALENT_SPEC]);
  297.     else
  298.         PlayerTalentFrame_Refresh();
  299.     end
  300.  
  301.     -- Set flag
  302.     if ( not GetCVarBool("talentFrameShown") ) then
  303.         SetCVar("talentFrameShown", 1);
  304.         UIFrameFlash(PlayerTalentFrameScrollButtonOverlay, 0.5, 0.5, 60);
  305.     end
  306. end
  307.  
  308. function  PlayerTalentFrame_OnHide()
  309.     UpdateMicroButtons();
  310.     PlaySound("TalentScreenClose");
  311.     UIFrameFlashStop(PlayerTalentFrameScrollButtonOverlay);
  312.     -- clear caches
  313.     for _, info in next, talentSpecInfoCache do
  314.         wipe(info);
  315.     end
  316.     wipe(talentTabWidthCache);
  317. end
  318.  
  319. function PlayerTalentFrame_OnEvent(self, event, ...)
  320.     if ( event == "PLAYER_TALENT_UPDATE" or event == "PET_TALENT_UPDATE" ) then
  321.         PlayerTalentFrame_Refresh();
  322.     elseif ( event == "PREVIEW_TALENT_POINTS_CHANGED" ) then
  323.         --local talentIndex, tabIndex, groupIndex, points = ...;
  324.         if ( selectedSpec and not specs[selectedSpec].pet ) then
  325.             PlayerTalentFrame_Refresh();
  326.         end
  327.     elseif ( event == "PREVIEW_PET_TALENT_POINTS_CHANGED" ) then
  328.         --local talentIndex, tabIndex, groupIndex, points = ...;
  329.         if ( selectedSpec and specs[selectedSpec].pet ) then
  330.             PlayerTalentFrame_Refresh();
  331.         end
  332.     elseif ( event == "UNIT_PORTRAIT_UPDATE" ) then
  333.         local unit = ...;
  334.         -- update the talent frame's portrait
  335.         if ( unit == PlayerTalentFramePortrait.unit ) then
  336.             SetPortraitTexture(PlayerTalentFramePortrait, unit);
  337.         end
  338.         -- update spec tabs' portraits
  339.         for _, frame in next, specTabs do
  340.             if ( frame.usingPortraitTexture ) then
  341.                 local spec = specs[frame.specIndex];
  342.                 if ( unit == spec.unit and spec.portraitUnit ) then
  343.                     SetPortraitTexture(frame:GetNormalTexture(), unit);
  344.                 end
  345.             end
  346.         end
  347.     elseif ( event == "UNIT_PET" ) then
  348.         local summoner = ...;
  349.         if ( summoner == "player" ) then
  350.             if ( selectedSpec and specs[selectedSpec].pet ) then
  351.                 -- if the selected spec is a pet spec...
  352.                 local numTalentGroups = GetNumTalentGroups(false, true);
  353.                 if ( numTalentGroups == 0 ) then
  354.                     --...and a pet spec is not available, select the default spec
  355.                     PlayerSpecTab_OnClick(activeSpec and specTabs[activeSpec] or specTabs[DEFAULT_TALENT_SPEC]);
  356.                     return;
  357.                 end
  358.             end
  359.             PlayerTalentFrame_Refresh();
  360.         end
  361.     elseif ( event == "PLAYER_LEVEL_UP" ) then
  362.         if ( selectedSpec and not specs[selectedSpec].pet ) then
  363.             local level = ...;
  364.             PlayerTalentFrame_Update(level);
  365.         end
  366.     elseif ( event == "ACTIVE_TALENT_GROUP_CHANGED" ) then
  367.         MainMenuBar_ToPlayerArt(MainMenuBarArtFrame);
  368.     end
  369. end
  370.  
  371. function PlayerTalentFrame_Refresh()
  372.     local selectedTab = PanelTemplates_GetSelectedTab(PlayerTalentFrame);
  373.     if ( selectedTab == GLYPH_TALENT_TAB ) then
  374.         PlayerTalentFrame_ShowGlyphFrame();
  375.     else
  376.         PlayerTalentFrame_HideGlyphFrame();
  377.     end
  378.     TalentFrame_Update(PlayerTalentFrame);
  379. end
  380.  
  381. function PlayerTalentFrame_Update(playerLevel)
  382.     local activeTalentGroup, numTalentGroups = GetActiveTalentGroup(false, false), GetNumTalentGroups(false, false);
  383.     local activePetTalentGroup, numPetTalentGroups = GetActiveTalentGroup(false, true), GetNumTalentGroups(false, true);
  384.  
  385.     -- update specs
  386.     if ( not PlayerTalentFrame_UpdateSpecs(activeTalentGroup, numTalentGroups, activePetTalentGroup, numPetTalentGroups) ) then
  387.         -- the current spec is not selectable any more, discontinue updates
  388.         return;
  389.     end
  390.  
  391.     -- update tabs
  392.     if ( not PlayerTalentFrame_UpdateTabs(playerLevel) ) then
  393.         -- the current spec is not selectable any more, discontinue updates
  394.         return;
  395.     end
  396.  
  397.     -- set the frame portrait
  398.     SetPortraitTexture(PlayerTalentFramePortrait, PlayerTalentFrame.unit);
  399.  
  400.     -- update active talent group stuff
  401.     PlayerTalentFrame_UpdateActiveSpec(activeTalentGroup, numTalentGroups);
  402.  
  403.     -- update talent controls
  404.     PlayerTalentFrame_UpdateControls(activeTalentGroup, numTalentGroups);
  405. end
  406.  
  407. function PlayerTalentFrame_UpdateActiveSpec(activeTalentGroup, numTalentGroups)
  408.     -- set the active spec
  409.     activeSpec = DEFAULT_TALENT_SPEC;
  410.     for index, spec in next, specs do
  411.         if ( not spec.pet and spec.talentGroup == activeTalentGroup ) then
  412.             activeSpec = index;
  413.             break;
  414.         end
  415.     end
  416.     -- make UI adjustments
  417.     local spec = selectedSpec and specs[selectedSpec];
  418.  
  419.     local hasMultipleTalentGroups = numTalentGroups > 1;
  420.     if ( spec and hasMultipleTalentGroups ) then
  421.         PlayerTalentFrameTitleText:SetText(spec.name);
  422.     else
  423.         PlayerTalentFrameTitleText:SetText(TALENTS);
  424.     end
  425.  
  426.     if ( selectedSpec == activeSpec and hasMultipleTalentGroups ) then
  427.         --PlayerTalentFrameActiveTalentGroupFrame:Show();
  428.     else
  429.         PlayerTalentFrameActiveTalentGroupFrame:Hide();
  430.     end
  431. end
  432.  
  433.  
  434. -- PlayerTalentFrameTalents
  435.  
  436. function PlayerTalentFrameTalent_OnClick(self, button)
  437.     if ( IsModifiedClick("CHATLINK") ) then
  438.         local link = GetTalentLink(PanelTemplates_GetSelectedTab(PlayerTalentFrame), self:GetID(),
  439.             PlayerTalentFrame.inspect, PlayerTalentFrame.pet, PlayerTalentFrame.talentGroup, GetCVarBool("previewTalents"));
  440.         if ( link ) then
  441.             ChatEdit_InsertLink(link);
  442.         end
  443.     elseif ( selectedSpec and (activeSpec == selectedSpec or specs[selectedSpec].pet) ) then
  444.         -- only allow functionality if an active spec is selected
  445.         if ( button == "LeftButton" ) then
  446.             if ( GetCVarBool("previewTalents") ) then
  447.                 AddPreviewTalentPoints(PanelTemplates_GetSelectedTab(PlayerTalentFrame), self:GetID(), 1, PlayerTalentFrame.pet, PlayerTalentFrame.talentGroup);
  448.             else
  449.                 LearnTalent(PanelTemplates_GetSelectedTab(PlayerTalentFrame), self:GetID(), PlayerTalentFrame.pet, PlayerTalentFrame.talentGroup);
  450.             end
  451.         elseif ( button == "RightButton" ) then
  452.             if ( GetCVarBool("previewTalents") ) then
  453.                 AddPreviewTalentPoints(PanelTemplates_GetSelectedTab(PlayerTalentFrame), self:GetID(), -1, PlayerTalentFrame.pet, PlayerTalentFrame.talentGroup);
  454.             end
  455.         end
  456.     end
  457. end
  458.  
  459. function PlayerTalentFrameTalent_OnEvent(self, event, ...)
  460.     if ( GameTooltip:IsOwned(self) ) then
  461.         GameTooltip:SetTalent(PanelTemplates_GetSelectedTab(PlayerTalentFrame), self:GetID(),
  462.             PlayerTalentFrame.inspect, PlayerTalentFrame.pet, PlayerTalentFrame.talentGroup, GetCVarBool("previewTalents"));
  463.     end
  464. end
  465.  
  466. function PlayerTalentFrameTalent_OnEnter(self)
  467.     GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
  468.     GameTooltip:SetTalent(PanelTemplates_GetSelectedTab(PlayerTalentFrame), self:GetID(),
  469.         PlayerTalentFrame.inspect, PlayerTalentFrame.pet, PlayerTalentFrame.talentGroup, GetCVarBool("previewTalents"));
  470.        
  471.     local canLearn = nil;
  472.     local wrapRest = false;
  473.     local l = GameTooltip:NumLines();
  474.     if (_G["GameTooltipTextLeft"..l]:GetText() == "Click to learn") then
  475.         canLearn = true;
  476.         wrapRest = true;
  477.         l = l - 1;
  478.     end
  479.     local tmp = {};
  480.     local r = true;
  481.     local i = 1;
  482.     for c=1, l do
  483.         r = true;
  484.         local n = {};
  485.         local left = _G["GameTooltipTextLeft"..c];
  486.         local right = _G["GameTooltipTextRight"..c];
  487.         if ( left ) then
  488.             n.w = true;
  489.             n.r1, n.g1, n.b1 = left:GetTextColor();
  490.             local t = left:GetText();
  491.             if ( strsub(t, 1, 8) == "Requires" ) then
  492.                 n.w = wrapRest;
  493.                 if ( strsub(t, -7) == "Talents" ) then
  494.                     local d = tonumber(strmatch(t, "%d+")) / 5;
  495.                     t = gsub(t, "%d+", d);
  496.                     wrapRest = true;
  497.                     if ( d <= PlayerTalentFrame.pointsSpent + PlayerTalentFrame.previewPointsSpent ) then
  498.                         n.r1 = 1.0; n.g1 = 1.0; n.b1 = 1.0;
  499.                         r = false;
  500.                         if ( canLearn == nil ) then
  501.                             canLearn = true;
  502.                         end
  503.                     end
  504.                 elseif ( not wrapRest ) then
  505.                     canLearn = false;
  506.                 end
  507.             end
  508.             n.t1 = t;
  509.         end
  510.         if ( right ) then
  511.             n.r2, n.g2, n.b2 = right:GetTextColor();
  512.             n.t2 = right:GetText();
  513.         end
  514.         if ( r ) then
  515.             tmp[i] = n;
  516.             i = i + 1;
  517.         end
  518.     end
  519.     i = nil;
  520.     GameTooltip:ClearLines();
  521.     for i=1, #tmp do
  522.         if ( tmp[i].t1 and tmp[i].t2 ) then
  523.             GameTooltip:AddDoubleLine(tmp[i].t1, tmp[i].t2, tmp[i].r1, tmp[i].g1, tmp[i].b1, tmp[i].r2, tmp[i].g2, tmp[i].b2);
  524.         elseif ( tmp[i].t1 ) then
  525.             GameTooltip:AddLine(tmp[i].t1, tmp[i].r1, tmp[i].g1, tmp[i].b1, tmp[i].w);
  526.         elseif ( tmp[i].t2 ) then
  527.             GameTooltip:AddDoubleLine("", tmp[i].t2, 0, 0, 0, tmp[i].r2, tmp[i].g2, tmp[i].b2);
  528.         end
  529.     end
  530.     if ( canLearn ) then
  531.         GameTooltip:AddLine("Click to learn", 0, 1, 0, true);
  532.     end
  533.     GameTooltip:Show();
  534. end
  535.  
  536.  
  537. -- Controls
  538.  
  539. function PlayerTalentFrame_UpdateControls(activeTalentGroup, numTalentGroups)
  540.     local spec = selectedSpec and specs[selectedSpec];
  541.  
  542.     local isActiveSpec = selectedSpec == activeSpec;
  543.  
  544.     -- show the multi-spec status frame if this is not a pet spec or we have more than one talent group
  545.     local showStatusFrame = not spec.pet and numTalentGroups > 1;
  546.     -- show the activate button if we were going to show the status frame but this is not the active spec
  547.     local showActivateButton = showStatusFrame and not isActiveSpec;
  548.     if ( showActivateButton ) then
  549.         PlayerTalentFrameActivateButton:Show();
  550.         PlayerTalentFrameStatusFrame:Hide();
  551.     else
  552.         PlayerTalentFrameActivateButton:Hide();
  553.         if ( showStatusFrame ) then
  554.             PlayerTalentFrameStatusFrame:Show();
  555.         else
  556.             PlayerTalentFrameStatusFrame:Hide();
  557.         end
  558.     end
  559.  
  560.     local preview = GetCVarBool("previewTalents");
  561.  
  562.     -- enable the control bar if this is the active spec, preview is enabled, and preview points were spent
  563.     local talentPoints = GetUnspentTalentPoints(false, spec.pet, spec.talentGroup);
  564.     if ( (spec.pet or isActiveSpec) and talentPoints > 0 and preview ) then
  565.         PlayerTalentFramePreviewBar:Show();
  566.         -- enable accept/cancel buttons if preview talent points were spent
  567.         if ( GetGroupPreviewTalentPointsSpent(spec.pet, spec.talentGroup) > 0 ) then
  568.             PlayerTalentFrameLearnButton:Enable();
  569.             PlayerTalentFrameResetButton:Enable();
  570.         else
  571.             PlayerTalentFrameLearnButton:Disable();
  572.             PlayerTalentFrameResetButton:Disable();
  573.         end
  574.         -- squish all frames to make room for this bar
  575.         PlayerTalentFramePointsBar:SetPoint("BOTTOM", PlayerTalentFramePreviewBar, "TOP", 0, -4);
  576.     else
  577.         PlayerTalentFramePreviewBar:Hide();
  578.         -- unsquish frames since the bar is now hidden
  579.         PlayerTalentFramePointsBar:SetPoint("BOTTOM", PlayerTalentFrame, "BOTTOM", 0, 81);
  580.     end
  581. end
  582.  
  583. function PlayerTalentFrameActivateButton_OnLoad(self)
  584.     self:SetWidth(self:GetTextWidth() + 40);
  585. end
  586.  
  587. function PlayerTalentFrameActivateButton_OnClick(self)
  588.     if ( selectedSpec ) then
  589.         local talentGroup = specs[selectedSpec].talentGroup;
  590.         if ( talentGroup ) then
  591.             SetActiveTalentGroup(talentGroup);
  592.         end
  593.     end
  594. end
  595.  
  596. function PlayerTalentFrameActivateButton_OnShow(self)
  597.     self:RegisterEvent("CURRENT_SPELL_CAST_CHANGED");
  598.     PlayerTalentFrameActivateButton_Update();
  599. end
  600.  
  601. function PlayerTalentFrameActivateButton_OnHide(self)
  602.     self:UnregisterEvent("CURRENT_SPELL_CAST_CHANGED");
  603. end
  604.  
  605. function PlayerTalentFrameActivateButton_OnEvent(self, event, ...)
  606.     PlayerTalentFrameActivateButton_Update();
  607. end
  608.  
  609. function PlayerTalentFrameActivateButton_Update()
  610.     local spec = selectedSpec and specs[selectedSpec];
  611.     if ( spec and PlayerTalentFrameActivateButton:IsShown() ) then
  612.         -- if the activation spell is being cast currently, disable the activate button
  613.         if ( IsCurrentSpell(TALENT_ACTIVATION_SPELLS[spec.talentGroup]) ) then
  614.             PlayerTalentFrameActivateButton:Disable();
  615.         else
  616.             PlayerTalentFrameActivateButton:Enable();
  617.         end
  618.     end
  619. end
  620.  
  621. function PlayerTalentFrameResetButton_OnEnter(self)
  622.     GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
  623.     GameTooltip:SetText(TALENT_TOOLTIP_RESETTALENTGROUP);
  624. end
  625.  
  626. function PlayerTalentFrameResetButton_OnClick(self)
  627.     ResetGroupPreviewTalentPoints(PlayerTalentFrame.pet, PlayerTalentFrame.talentGroup);
  628. end
  629.  
  630. function PlayerTalentFrameLearnButton_OnEnter(self)
  631.     GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
  632.     GameTooltip:SetText(TALENT_TOOLTIP_LEARNTALENTGROUP);
  633. end
  634.  
  635. function PlayerTalentFrameLearnButton_OnClick(self)
  636.     StaticPopup_Show("CONFIRM_LEARN_PREVIEW_TALENTS");
  637. end
  638.  
  639.  
  640. -- PlayerTalentFrameDownArrow
  641.  
  642. function PlayerTalentFrameDownArrow_OnClick(self, button)
  643.     local parent = self:GetParent();
  644.     parent:SetValue(parent:GetValue() + (parent:GetHeight() / 2));
  645.     PlaySound("UChatScrollButton");
  646.     UIFrameFlashStop(PlayerTalentFrameScrollButtonOverlay);
  647. end
  648.  
  649.  
  650. -- PlayerTalentFrameTab
  651.  
  652. function PlayerTalentFrame_UpdateTabs(playerLevel)
  653.     local totalTabWidth = 0;
  654.  
  655.     local firstShownTab;
  656.  
  657.     -- setup talent tabs
  658.     local maxPointsSpent = 0;
  659.     local selectedTab = PanelTemplates_GetSelectedTab(PlayerTalentFrame);
  660.     local numTabs = GetNumTalentTabs(PlayerTalentFrame.inspect, PlayerTalentFrame.pet);
  661.     local tab;
  662.     for i = 1, MAX_TALENT_TABS do
  663.         -- clear cached widths
  664.         talentTabWidthCache[i] = 0;
  665.         tab = _G["PlayerTalentFrameTab"..i];
  666.         if ( tab ) then
  667.             if ( i <= numTabs ) then
  668.                 local name, icon, pointsSpent, background, previewPointsSpent = GetTalentTabInfo(i, PlayerTalentFrame.inspect, PlayerTalentFrame.pet, PlayerTalentFrame.talentGroup);
  669.                 if ( i == selectedTab ) then
  670.                     -- If tab is the selected tab set the points spent info
  671.                     local displayPointsSpent = pointsSpent + previewPointsSpent;
  672.                     PlayerTalentFrameSpentPointsText:SetFormattedText(MASTERY_POINTS_SPENT, name, HIGHLIGHT_FONT_COLOR_CODE..displayPointsSpent..FONT_COLOR_CODE_CLOSE);
  673.                     PlayerTalentFrame.pointsSpent = pointsSpent;
  674.                     PlayerTalentFrame.previewPointsSpent = previewPointsSpent;
  675.                 end
  676.                 tab:SetText(name);
  677.                 PanelTemplates_TabResize(tab, 0);
  678.                 -- record the text width to see if we need to display a tooltip
  679.                 tab.textWidth = tab:GetTextWidth();
  680.                 -- record the tab widths for resizing later
  681.                 talentTabWidthCache[i] = PanelTemplates_GetTabWidth(tab);
  682.                 totalTabWidth = totalTabWidth + talentTabWidthCache[i];
  683.                 tab:Show();
  684.                 firstShownTab = firstShownTab or tab;
  685.             else
  686.                 tab:Hide();
  687.                 tab.textWidth = 0;
  688.             end
  689.         end
  690.     end
  691.  
  692.     local spec = specs[selectedSpec];
  693.  
  694.     -- setup glyph tabs, right now there is only one
  695.     playerLevel = playerLevel or UnitLevel("player");
  696.     local meetsGlyphLevel = playerLevel >= SHOW_INSCRIPTION_LEVEL;
  697.     tab = _G["PlayerTalentFrameTab"..GLYPH_TALENT_TAB];
  698.     if ( meetsGlyphLevel and spec.hasGlyphs ) then
  699.         tab:Show();
  700.         firstShownTab = firstShownTab or tab;
  701.         PanelTemplates_TabResize(tab, 0);
  702.         talentTabWidthCache[GLYPH_TALENT_TAB] = PanelTemplates_GetTabWidth(tab);
  703.         totalTabWidth = totalTabWidth + talentTabWidthCache[GLYPH_TALENT_TAB];
  704.     else
  705.         tab:Hide();
  706.         talentTabWidthCache[GLYPH_TALENT_TAB] = 0;
  707.     end
  708.     local numGlyphTabs = 1;
  709.  
  710.     -- select the first shown tab if the selected tab does not exist for the selected spec
  711.     tab = _G["PlayerTalentFrameTab"..selectedTab];
  712.     if ( tab and not tab:IsShown() ) then
  713.         if ( firstShownTab ) then
  714.             PlayerTalentFrameTab_OnClick(firstShownTab);
  715.         end
  716.         return false;
  717.     end
  718.  
  719.     -- readjust tab sizes to fit
  720.     local maxTotalTabWidth = PlayerTalentFrame:GetWidth();
  721.     while ( totalTabWidth >= maxTotalTabWidth ) do
  722.         -- progressively shave 10 pixels off of the largest tab until they all fit within the max width
  723.         local largestTab = 1;
  724.         for i = 2, #talentTabWidthCache do
  725.             if ( talentTabWidthCache[largestTab] < talentTabWidthCache[i] ) then
  726.                 largestTab = i;
  727.             end
  728.         end
  729.         -- shave the width
  730.         talentTabWidthCache[largestTab] = talentTabWidthCache[largestTab] - 10;
  731.         -- apply the shaved width
  732.         tab = _G["PlayerTalentFrameTab"..largestTab];
  733.         PanelTemplates_TabResize(tab, 0, talentTabWidthCache[largestTab]);
  734.         -- now update the total width
  735.         totalTabWidth = totalTabWidth - 10;
  736.     end
  737.  
  738.     -- update the tabs
  739.     PanelTemplates_SetNumTabs(PlayerTalentFrame, numTabs + numGlyphTabs);
  740.     PanelTemplates_UpdateTabs(PlayerTalentFrame);
  741.  
  742.     return true;
  743. end
  744.  
  745. function PlayerTalentFrameTab_OnLoad(self)
  746.     self:SetFrameLevel(self:GetFrameLevel() + 2);
  747. end
  748.  
  749. function PlayerTalentFrameTab_OnClick(self)
  750.     local id = self:GetID();
  751.     PanelTemplates_SetTab(PlayerTalentFrame, id);
  752.     PlayerTalentFrame_Refresh();
  753.     PlaySound("igCharacterInfoTab");
  754. end
  755.  
  756. function PlayerTalentFrameTab_OnEnter(self)
  757.     if ( self.textWidth and self.textWidth > self:GetFontString():GetWidth() ) then --We're ellipsizing.
  758.         GameTooltip:SetOwner(self, "ANCHOR_BOTTOM");
  759.         GameTooltip:SetText(self:GetText());
  760.     end
  761. end
  762.  
  763.  
  764. -- PlayerTalentTab
  765.  
  766. function PlayerTalentTab_OnLoad(self)
  767.     PlayerTalentFrameTab_OnLoad(self);
  768.  
  769.     self:RegisterEvent("PLAYER_LEVEL_UP");
  770. end
  771.  
  772. function PlayerTalentTab_OnClick(self)
  773.     PlayerTalentFrameTab_OnClick(self);
  774.     for i=1, MAX_TALENT_TABS do
  775.         SetButtonPulse(_G["PlayerTalentFrameTab"..i], 0, 0);
  776.     end
  777. end
  778.  
  779. function PlayerTalentTab_OnEvent(self, event, ...)
  780.     if ( UnitLevel("player") == (SHOW_TALENT_LEVEL - 1) and PanelTemplates_GetSelectedTab(PlayerTalentFrame) ~= self:GetID() ) then
  781.         SetButtonPulse(self, 60, 0.75);
  782.     end
  783. end
  784.  
  785. function PlayerTalentTab_GetBestDefaultTab(specIndex)
  786.     if ( not specIndex ) then
  787.         return DEFAULT_TALENT_TAB;
  788.     end
  789.  
  790.     local spec = specs[specIndex];
  791.     if ( not spec ) then
  792.         return DEFAULT_TALENT_TAB;
  793.     end
  794.  
  795.     local specInfoCache = talentSpecInfoCache[specIndex];
  796.     TalentFrame_UpdateSpecInfoCache(specInfoCache, false, spec.pet, spec.talentGroup);
  797.     if ( specInfoCache.primaryTabIndex > 0 ) then
  798.         return talentSpecInfoCache[specIndex].primaryTabIndex;
  799.     else
  800.         return DEFAULT_TALENT_TAB;
  801.     end
  802. end
  803.  
  804.  
  805. -- PlayerGlyphTab
  806.  
  807. function PlayerGlyphTab_OnLoad(self)
  808.     PlayerTalentFrameTab_OnLoad(self);
  809.  
  810.     self:RegisterEvent("PLAYER_LEVEL_UP");
  811.     GLYPH_TALENT_TAB = self:GetID();
  812.     -- we can record the text width for the glyph tab now since it never changes
  813.     self.textWidth = self:GetTextWidth();
  814. end
  815.  
  816. function PlayerGlyphTab_OnClick(self)
  817.     PlayerTalentFrameTab_OnClick(self);
  818.     SetButtonPulse(_G["PlayerTalentFrameTab"..GLYPH_TALENT_TAB], 0, 0);
  819. end
  820.  
  821. function PlayerGlyphTab_OnEvent(self, event, ...)
  822.     if ( UnitLevel("player") == (SHOW_INSCRIPTION_LEVEL - 1) and PanelTemplates_GetSelectedTab(PlayerTalentFrame) ~= self:GetID() ) then
  823.         SetButtonPulse(self, 60, 0.75);
  824.     end
  825. end
  826.  
  827.  
  828. -- Specs
  829.  
  830. -- PlayerTalentFrame_UpdateSpecs is a helper function for PlayerTalentFrame_Update.
  831. -- Returns true on a successful update, false otherwise. An update may fail if the currently
  832. -- selected tab is no longer selectable. In this case, the first selectable tab will be selected.
  833. function PlayerTalentFrame_UpdateSpecs(activeTalentGroup, numTalentGroups, activePetTalentGroup, numPetTalentGroups)
  834.     -- set the active spec highlight to be hidden initially, if a spec is the active one then it will
  835.     -- be shown in PlayerSpecTab_Update
  836.     PlayerTalentFrameActiveSpecTabHighlight:Hide();
  837.  
  838.     -- update each of the spec tabs
  839.     local firstShownTab, lastShownTab;
  840.     local numShown = 0;
  841.     local offsetX = 0;
  842.     for i = 1, numSpecTabs do
  843.         local frame = _G["PlayerSpecTab"..i];
  844.         local specIndex = frame.specIndex;
  845.         local spec = specs[specIndex];
  846.         if ( PlayerSpecTab_Update(frame, activeTalentGroup, numTalentGroups, activePetTalentGroup, numPetTalentGroups) ) then
  847.             firstShownTab = firstShownTab or frame;
  848.             numShown = numShown + 1;
  849.             frame:ClearAllPoints();
  850.             -- set an offsetX fudge if we're the selected tab, otherwise use the previous offsetX
  851.             offsetX = specIndex == selectedSpec and SELECTEDSPEC_OFFSETX or offsetX;
  852.             if ( numShown == 1 ) then
  853.                 --...start the first tab off at a base location
  854.                 frame:SetPoint("TOPLEFT", frame:GetParent(), "TOPRIGHT", -32 + offsetX, -65);
  855.                 -- we'll need to negate the offsetX after the first tab so all subsequent tabs offset
  856.                 -- to their default positions
  857.                 offsetX = -offsetX;
  858.             else
  859.                 --...offset subsequent tabs from the previous one
  860.                 if ( spec.pet ~= specs[lastShownTab.specIndex].pet ) then
  861.                     frame:SetPoint("TOPLEFT", lastShownTab, "BOTTOMLEFT", 0 + offsetX, -39);
  862.                 else
  863.                     frame:SetPoint("TOPLEFT", lastShownTab, "BOTTOMLEFT", 0 + offsetX, -22);
  864.                 end
  865.             end
  866.             lastShownTab = frame;
  867.         else
  868.             -- if the selected tab is not shown then clear out the selected spec
  869.             if ( specIndex == selectedSpec ) then
  870.                 selectedSpec = nil;
  871.             end
  872.         end
  873.     end
  874.  
  875.     if ( not selectedSpec ) then
  876.         if ( firstShownTab ) then
  877.             PlayerSpecTab_OnClick(firstShownTab);
  878.         end
  879.         return false;
  880.     end
  881.  
  882.     if ( numShown == 1 and lastShownTab ) then
  883.         -- if we're only showing one tab, we might as well hide it since it doesn't need to be there
  884.         lastShownTab:Hide();
  885.     end
  886.  
  887.     return true;
  888. end
  889.  
  890. function PlayerSpecTab_Update(self, ...)
  891.     local activeTalentGroup, numTalentGroups, activePetTalentGroup, numPetTalentGroups = ...;
  892.  
  893.     local specIndex = self.specIndex;
  894.     local spec = specs[specIndex];
  895.  
  896.     -- determine whether or not we need to hide the tab
  897.     local canShow;
  898.     if ( spec.pet ) then
  899.         canShow = spec.talentGroup <= numPetTalentGroups;
  900.     else
  901.         canShow = spec.talentGroup <= numTalentGroups;
  902.     end
  903.     if ( not canShow ) then
  904.         self:Hide();
  905.         return false;
  906.     end
  907.  
  908.     local isSelectedSpec = specIndex == selectedSpec;
  909.     local isActiveSpec = not spec.pet and spec.talentGroup == activeTalentGroup;
  910.     local normalTexture = self:GetNormalTexture();
  911.  
  912.     -- set the background based on whether or not we're selected
  913.     if ( isSelectedSpec and (SELECTEDSPEC_DISPLAYTYPE == "PUSHED_OUT" or SELECTEDSPEC_DISPLAYTYPE == "PUSHED_OUT_CHECKED") ) then
  914.         local name = self:GetName();
  915.         local backgroundTexture = _G[name.."Background"];
  916.         backgroundTexture:SetTexture("Interface\\TalentFrame\\UI-TalentFrame-SpecTab");
  917.         backgroundTexture:SetPoint("TOPLEFT", self, "TOPLEFT", -13, 11);
  918.         if ( SELECTEDSPEC_DISPLAYTYPE == "PUSHED_OUT_CHECKED" ) then
  919.             self:GetCheckedTexture():Show();
  920.         else
  921.             self:GetCheckedTexture():Hide();
  922.         end
  923.     else
  924.         local name = self:GetName();
  925.         local backgroundTexture = _G[name.."Background"];
  926.         backgroundTexture:SetTexture("Interface\\SpellBook\\SpellBook-SkillLineTab");
  927.         backgroundTexture:SetPoint("TOPLEFT", self, "TOPLEFT", -3, 11);
  928.     end
  929.  
  930.     -- update the active spec info
  931.     local hasMultipleTalentGroups = numTalentGroups > 1;
  932.     if ( isActiveSpec and hasMultipleTalentGroups ) then
  933.         PlayerTalentFrameActiveSpecTabHighlight:ClearAllPoints();
  934.         if ( ACTIVESPEC_DISPLAYTYPE == "BLUE" ) then
  935.             PlayerTalentFrameActiveSpecTabHighlight:SetParent(self);
  936.             PlayerTalentFrameActiveSpecTabHighlight:SetPoint("TOPLEFT", self, "TOPLEFT", -13, 14);
  937.             PlayerTalentFrameActiveSpecTabHighlight:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", 15, -14);
  938.             PlayerTalentFrameActiveSpecTabHighlight:Show();
  939.         elseif ( ACTIVESPEC_DISPLAYTYPE == "GOLD_INSIDE" ) then
  940.             PlayerTalentFrameActiveSpecTabHighlight:SetParent(self);
  941.             PlayerTalentFrameActiveSpecTabHighlight:SetAllPoints(self);
  942.             PlayerTalentFrameActiveSpecTabHighlight:Show();
  943.         elseif ( ACTIVESPEC_DISPLAYTYPE == "GOLD_BACKGROUND" ) then
  944.             PlayerTalentFrameActiveSpecTabHighlight:SetParent(self);
  945.             PlayerTalentFrameActiveSpecTabHighlight:SetPoint("TOPLEFT", self, "TOPLEFT", -3, 20);
  946.             PlayerTalentFrameActiveSpecTabHighlight:Show();
  947.         else
  948.             PlayerTalentFrameActiveSpecTabHighlight:Hide();
  949.         end
  950.     end
  951.  
  952. --[[
  953.     if ( not spec.pet ) then
  954.         SetDesaturation(normalTexture, not isActiveSpec);
  955.     end
  956. --]]
  957.  
  958.     -- update the spec info cache
  959.     TalentFrame_UpdateSpecInfoCache(talentSpecInfoCache[specIndex], false, spec.pet, spec.talentGroup);
  960.  
  961.     -- update spec tab icon
  962.     self.usingPortraitTexture = false;
  963.     if ( hasMultipleTalentGroups ) then
  964.         local specInfoCache = talentSpecInfoCache[specIndex];
  965.         local primaryTabIndex = specInfoCache.primaryTabIndex;
  966.         if ( primaryTabIndex > 0 ) then
  967.             -- the spec had a primary tab, set the icon to that tab's icon
  968.             normalTexture:SetTexture(specInfoCache[primaryTabIndex].icon);
  969.         else
  970.             if ( specInfoCache.numTabs > 1 and specInfoCache.totalPointsSpent > 0 ) then
  971.                 -- the spec is only considered a hybrid if the spec had more than one tab and at least
  972.                 -- one point was spent in one of the tabs
  973.                 normalTexture:SetTexture(TALENT_HYBRID_ICON);
  974.             else
  975.                 if ( spec.defaultSpecTexture ) then
  976.                     -- the spec is probably untalented...set to the default spec texture if we have one
  977.                     normalTexture:SetTexture(spec.defaultSpecTexture);
  978.                 elseif ( spec.portraitUnit ) then
  979.                     -- last check...if there is no default spec texture, try the portrait unit
  980.                     SetPortraitTexture(normalTexture, spec.portraitUnit);
  981.                     self.usingPortraitTexture = true;
  982.                 end
  983.             end
  984.         end
  985.     else
  986.         if ( spec.portraitUnit ) then
  987.             -- set to the portrait texture if we only have one talent group
  988.             SetPortraitTexture(normalTexture, spec.portraitUnit);
  989.             self.usingPortraitTexture = true;
  990.         end
  991.     end
  992. --[[
  993.     -- update overlay icon
  994.     local name = self:GetName();
  995.     local overlayIcon = _G[name.."OverlayIcon"];
  996.     if ( overlayIcon ) then
  997.         if ( hasMultipleTalentGroups ) then
  998.             overlayIcon:Show();
  999.         else
  1000.             overlayIcon:Hide();
  1001.         end
  1002.     end
  1003. --]]
  1004.     self:Show();
  1005.     return true;
  1006. end
  1007.  
  1008. function PlayerSpecTab_Load(self, specIndex)
  1009.     self.specIndex = specIndex;
  1010.     specTabs[specIndex] = self;
  1011.     numSpecTabs = numSpecTabs + 1;
  1012.  
  1013.     -- set the spec's portrait
  1014.     local spec = specs[self.specIndex];
  1015.     if ( spec.portraitUnit ) then
  1016.         SetPortraitTexture(self:GetNormalTexture(), spec.portraitUnit);
  1017.         self.usingPortraitTexture = true;
  1018.     else
  1019.         self.usingPortraitTexture = false;
  1020.     end
  1021.  
  1022.     -- set the checked texture
  1023.     if ( SELECTEDSPEC_DISPLAYTYPE == "BLUE" ) then
  1024.         local checkedTexture = self:GetCheckedTexture();
  1025.         checkedTexture:SetTexture("Interface\\Buttons\\UI-Button-Outline");
  1026.         checkedTexture:SetWidth(64);
  1027.         checkedTexture:SetHeight(64);
  1028.         checkedTexture:ClearAllPoints();
  1029.         checkedTexture:SetPoint("CENTER", self, "CENTER", 0, 0);
  1030.     elseif ( SELECTEDSPEC_DISPLAYTYPE == "GOLD_INSIDE" ) then
  1031.         local checkedTexture = self:GetCheckedTexture();
  1032.         checkedTexture:SetTexture("Interface\\Buttons\\CheckButtonHilight");
  1033.     end
  1034.  
  1035.     local activeTalentGroup, numTalentGroups = GetActiveTalentGroup(false, false), GetNumTalentGroups(false, false);
  1036.     local activePetTalentGroup, numPetTalentGroups = GetActiveTalentGroup(false, true), GetNumTalentGroups(false, true);
  1037.     PlayerSpecTab_Update(self, activeTalentGroup, numTalentGroups, activePetTalentGroup, numPetTalentGroups);
  1038. end
  1039.  
  1040. function PlayerSpecTab_OnClick(self)
  1041.     -- set all specs as unchecked initially
  1042.     for _, frame in next, specTabs do
  1043.         frame:SetChecked(nil);
  1044.     end
  1045.  
  1046.     -- check ourselves (before we wreck ourselves)
  1047.     self:SetChecked(1);
  1048.  
  1049.     -- update the selected to this spec
  1050.     local specIndex = self.specIndex;
  1051.     selectedSpec = specIndex;
  1052.  
  1053.     -- set data on the talent frame
  1054.     local spec = specs[specIndex];
  1055.     PlayerTalentFrame.pet = spec.pet;
  1056.     PlayerTalentFrame.unit = spec.unit;
  1057.     PlayerTalentFrame.talentGroup = spec.talentGroup;
  1058.  
  1059.     -- select a tab if one is not already selected
  1060.     if ( not PanelTemplates_GetSelectedTab(PlayerTalentFrame) ) then
  1061.         PanelTemplates_SetTab(PlayerTalentFrame, PlayerTalentTab_GetBestDefaultTab(specIndex));
  1062.     end
  1063.  
  1064.     -- update the talent frame
  1065.     PlayerTalentFrame_Refresh();
  1066. end
  1067.  
  1068. function PlayerSpecTab_OnEnter(self)
  1069.     local specIndex = self.specIndex;
  1070.     local spec = specs[specIndex];
  1071.     if ( spec.tooltip ) then
  1072.         GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
  1073.         -- name
  1074.         if ( GetNumTalentGroups(false, true) <= 1 and GetNumTalentGroups(false, false) <= 1 ) then
  1075.             -- set the tooltip to be the unit's name
  1076.             GameTooltip:AddLine(UnitName(spec.unit), NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b);
  1077.         else
  1078.             -- set the tooltip to be the spec name
  1079.             GameTooltip:AddLine(spec.tooltip);
  1080.             if ( self.specIndex == activeSpec ) then
  1081.                 -- add text to indicate that this spec is active
  1082.                 GameTooltip:AddLine(TALENT_ACTIVE_SPEC_STATUS, GREEN_FONT_COLOR.r, GREEN_FONT_COLOR.g, GREEN_FONT_COLOR.b);
  1083.             end
  1084.         end
  1085.         -- points spent
  1086.         local pointsColor;
  1087.         for index, info in ipairs(talentSpecInfoCache[specIndex]) do
  1088.             if ( info.name ) then
  1089.                 -- assign a special color to a tab that surpasses the max points spent threshold
  1090.                 if ( talentSpecInfoCache[specIndex].primaryTabIndex == index ) then
  1091.                     pointsColor = GREEN_FONT_COLOR;
  1092.                 else
  1093.                     pointsColor = HIGHLIGHT_FONT_COLOR;
  1094.                 end
  1095.                 GameTooltip:AddDoubleLine(
  1096.                     info.name,
  1097.                     info.pointsSpent,
  1098.                     HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b,
  1099.                     pointsColor.r, pointsColor.g, pointsColor.b,
  1100.                     1
  1101.                 );
  1102.             end
  1103.         end
  1104.         GameTooltip:Show();
  1105.     end
  1106. end
Advertisement
Add Comment
Please, Sign In to add comment